home *** CD-ROM | disk | FTP | other *** search
- //concalc version 1.4,
- //written by Tarvo Korrovits in December, 2001,
- //original version made by Varun Ranjit Singh,
- //distributed under GNU General Public License
- //(there is no warranty).
- //"Do not create console" unchecked in Dev-C++ project
- //options, libcomdlg32.a shall be in object files box.
- //http://sourceforge.net/projects/tkorrovi
-
- #include <windows.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
-
- enum COLORS {BLACK, BLUE, GREEN, CYAN, RED, MAGENTA,
- BROWN, LIGHTGRAY, DARKGRAY, LIGHTBLUE, LIGHTGREEN,
- LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE};
-
- #define TEXTCOLOR BLACK + (WHITE << 4)
- #define ERRORCOLOR RED + (WHITE << 4)
- #define VALUECOLOR CYAN + (WHITE << 4)
- #define FORMULACOLOR MAGENTA + (WHITE << 4)
- #define BLANKCOLOR WHITE + (WHITE << 4)
- #define HEADERCOLOR WHITE + (CYAN << 4)
- #define HIGHLIGHTCOLOR WHITE + (DARKGRAY << 4)
- #define HIGHLIGHTERRORCOLOR WHITE + (RED << 4)
- #define MSGAUTOCALCCOLOR CYAN + (WHITE << 4)
- #define MSGFORMDISPLAYCOLOR MAGENTA + (WHITE << 4)
- #define MSGMEMORYCOLOR GREEN + (WHITE << 4)
- #define MSGHEADERCOLOR CYAN + (WHITE << 4)
- #define PROMPTCOLOR BROWN + (WHITE << 4)
- #define COMMANDCOLOR CYAN + (WHITE << 4)
- #define LOWCOMMANDCOLOR BLACK + (WHITE << 4)
- #define MEMORYCOLOR RED + (WHITE << 4)
- #define CELLTYPECOLOR GREEN + (WHITE << 4)
- #define CELLCONTENTSCOLOR BROWN + (WHITE << 4)
- #define MSGTITLE "concalc 1.4, distributed under GNU General Public License (no warranty)"
- #define MSGABOUT1 "Modified, copying and tsv added by Tarvo Korrovits.\n"
- #define MSGABOUT2 "originally made by Varun Ranjit Singh"
- #define MSGKEYPRESS "Press any key to continue."
- #define MSGCOMMAND "Press / for the list of commands"
- #define MSGMEMORY "Memory Available:"
- #define MSGERROR "ERROR"
- #define MSGLOMEM "Not enough memory to allocate cell."
- #define MSGEMPTY "Empty"
- #define MSGTEXT "Text"
- #define MSGVALUE "Value"
- #define MSGFORMULA "Formula"
- #define MSGAUTOCALC "AutoCalc"
- #define MSGFORMDISPLAY "Form"
- #define MSGFILENAME "Enter the file name of the spreadsheet:"
- #define MSGCOLWIDTH "Enter the new column width:"
- #define MSGNOOPEN "Can't open the file."
- #define MSGOVERWRITE "The file exists. Do you want to overwrite it?"
- #define MSGFILELOMEM "Not enough memory for entire spreadsheet."
- #define MSGNOEXIST "The file does not exist."
- #define MSGGOTO "Enter the cell to go to:"
- #define MSGBADNUMBER "You must enter a number from %d to %d."
- #define MSGBADCELL "That is not a legal cell."
- #define MSGRIGHTJUST "Do you want the cell right-justified?"
- #define MSGDOLLAR "Do you want numbers in a dollar format?"
- #define MSGCOMMAS "Do you want commas in numbers?"
- #define MSGPLACES "How many decimal places should the number be rounded to?"
- #define MSGCOLUMNS "Do you want to print in 132 columns?"
- #define MSGBORDER "Print the border?"
- #define MSGLOADING "Loading..."
- #define MSGSAVING "Saving..."
- #define MSGSAVESHEET "Save current spreadsheet?"
- #define MSGSTACKERROR "Parser stack overflow."
- #define MSGIOERROR "i/o error"
- #define MENU "Spreadsheet, Format, Delete, Goto, Col, Row, Edit, Utility, Auto, Quit"
- #define COMMAND "SFDGCREUAQ"
- #define SMENU "Load, Save, Print, Clear, About"
- #define SCOMMAND "LSPCA"
- #define CMENU "Insert, Delete, Width"
- #define CCOMMAND "IDW"
- #define RMENU "Insert, Delete"
- #define RCOMMAND "ID"
- #define UMENU "Recalc, Formula display"
- #define UCOMMAND "RF"
- #define S_IREAD 0x0100
- #define S_IWRITE 0x0080
- #define TRUE 1
- #define FALSE 0
- #define DOUBLE double
- #define MAXCOLS 100
- #define MAXROWS 999
- #define LEFTMARGIN 3
- #define MINCOLWIDTH 3
- #define MAXCOLWIDTH 80 - LEFTMARGIN
- #define SCREENCOLS (80 - LEFTMARGIN) / MINCOLWIDTH + 1
- #define SCREENROWS 20
- #define DEFAULTWIDTH 10
- #define DEFAULTFORMAT 0X42
- #define MAXINPUT 79
- #define MAXPLACES 8
- #define TOPMARGIN 5
- #define PARSERSTACKSIZE 200
- #define HIGHLIGHT TRUE
- #define NOHIGHLIGHT FALSE
- #define UPDATE TRUE
- #define NOUPDATE FALSE
- #define FORMAT TRUE
- #define NOFORMAT FALSE
- #define LEFT 0
- #define RIGHT 1
- #define UP 2
- #define DOWN 3
- #define TEXTCELL 0
- #define VALUE 1
- #define FORMULA 2
- #define COLADD 0
- #define COLDEL 1
- #define ROWADD 2
- #define ROWDEL 3
- #define OVERWRITE 0X80
- #define RJUSTIFY 0X40
- #define COMMAS 0X20
- #define DOLLAR 0X10
- #define BS 8
- #define FORMFEED 12
- #define CR 13
- #define ESC 27
- #define HOMEKEY 327
- #define ENDKEY 335
- #define UPKEY 328
- #define DOWNKEY 336
- #define PGUPKEY 329
- #define PGDNKEY 337
- #define LEFTKEY 331
- #define INSKEY 338
- #define RIGHTKEY 333
- #define DELKEY 339
- #define CTRLLEFTKEY 371
- #define CTRLRIGHTKEY 372
- #define F9 315
- #define F2 316
- #define SHIFTUPKEY 401
- #define SHIFTDOWNKEY 402
- #define SHIFTLEFTKEY 403
- #define SHIFTRIGHTKEY 404
- #define CTRLC 405
- #define CTRLV 406
- #define ALTF4 407
- #define F4 408
- #define TABKEY 409
- #define SHIFTENDKEY 410
- #define SHIFTF9 411
- #define PLUS 0
- #define MINUS 1
- #define TIMES 2
- #define DIVIDE 3
- #define EXP 4
- #define COLON 5
- #define OPAREN 6
- #define CPAREN 7
- #define NUM 8
- #define CELL 9
- #define FUNC 10
- #define EOLN 11
- #define BAD 12
- #define MAXFUNCNAMELEN 5
- #define RPLUS 1
- #define RMINUS 2
- #define RTIMES 4
- #define RDIVIDE 5
- #define RPOW 7
- #define RNEGATE 9
- #define RSUM 11
- #define RCELLVALUE 13
- #define RFUNC 16
- #define RNUM 15
- #define RCPAREN 14
- #define RFIRSTPOW 6
- #define RFIRSTNEGATE 8
- #define RFIRSTSUM 10
- #define RFIRSTFUNC 12
- #define RFIRSTTIMES 3
- #define SNUM 10
- #define SCELL 7
- #define SFUNC 11
- #define SNEGATE 5
- #define SOPAREN 9
- #define SPLUS 12
- #define SMINUS 13
- #define STIMES 14
- #define SDIVIDE 15
- #define SFIRST 0
- #define SPOW 16
- #define SCOLON 18
- #define SFOPAREN 20
- #define SDONEGATE 17
- #define SDOTIMES 23
- #define SDODIVIDE 24
- #define SDOPOW 25
- #define SDOSUM 26
- #define SDOFUNC 29
- #define SERROR 30
- #define SCPAREN 27
- #define SFIRSTPLUS 1
- #define SOPARENPLUS 19
- #define SFOPARENPLUS 28
- #define SFIRSTTIMES 2
- #define SFIRSTPOW 3
- #define SFIRSTNEGATE 4
- #define SFIRSTSUM 6
- #define SPLUSTIMES 21
- #define SMINUSTIMES 22
- #define SFIRSTFUNC 8
-
- struct CELLREC
- {
- CHAR attrib;
- union
- {
- CHAR text [MAXINPUT + 1];
- DOUBLE value;
- struct
- {
- DOUBLE fvalue;
- CHAR formula [MAXINPUT + 1];
- } f;
- } v;
- };
-
- typedef struct CELLREC *CELLPTR;
-
- struct TOKENREC
- {
- CHAR state;
- union
- {
- DOUBLE value;
- struct
- {
- INT row, col;
- } c;
- CHAR funcname [MAXFUNCNAMELEN + 1];
- } x;
- };
-
- INT getkey (VOID);
- INT editstring (LPSTR s, LPSTR legal, INT maxlength);
- INT getint (LPINT number, INT low, INT high);
- VOID scroll (INT direction, INT lines, INT x1, INT y1,
- INT x2, INT y2, INT attrib);
- VOID setcursor (UINT shape);
- VOID writef (INT col, INT row, INT color, INT width,
- LPSTR format, ...);
- VOID printcol (VOID);
- VOID displaycell (INT col, INT row, INT highlighting,
- INT updating);
- VOID displaycol (INT col, INT updating);
- VOID displayrow (INT row, INT updating);
- VOID displayscreen (INT updating);
- VOID showcelltype (VOID);
- DOUBLE parse (LPSTR s, LPINT att);
- INT alloctext (INT col, INT row, LPSTR s);
- INT allocvalue (INT col, INT row, DOUBLE amt);
- INT allocformula (INT col, INT row, LPSTR s, DOUBLE amt);
- VOID deletecell (INT col, INT row, INT display);
- VOID printfreemem (VOID);
- VOID moverowup (VOID);
- VOID moverowdown (VOID);
- VOID movecolleft (VOID);
- VOID movecolright (VOID);
- VOID recalc (VOID);
- VOID changeautocalc (INT newmode);
- VOID changeformdisplay (INT newmode);
- VOID errormsg (LPSTR s);
- VOID colstring (INT col, LPSTR colstr);
- VOID centercolstring (INT col, LPSTR colstr);
- VOID setleftcol (VOID);
- VOID setrightcol (VOID);
- VOID setbottomrow (VOID);
- VOID setlastcol (VOID);
- VOID setlastrow (VOID);
- VOID act (LPSTR s);
- VOID initvars (VOID);
- INT getcommand (LPSTR msgstr, LPSTR comstr);
- VOID mainmenu (VOID);
- VOID editcell (CELLPTR ecell);
- INT setoflags (INT col, INT row, INT display);
- VOID clearoflags (INT col, INT row, INT display);
- VOID updateoflags (INT col, INT row, INT display);
- VOID loadsheet (BOOL comline);
- INT getcell (LPINT col, LPINT row);
- LPSTR cellstring (INT col, INT row, LPINT color,
- INT formatting);
- INT getyesno (LPINT yesno, LPSTR prompt);
- VOID savesheet (VOID);
- INT formulastart (LPSTR *input, LPINT col, LPINT row);
- INT rowwidth (INT row);
- VOID fixformula (INT col, INT row, INT action,
- INT place);
- VOID clearlastcol (VOID);
- VOID setrect (INT left, INT top, INT right, INT bottom);
- VOID movetext (INT left, INT top, INT right, INT bottom,
- INT newleft, INT newtop);
- BOOL iscorrectkey (VOID);
- VOID fixformula2 (INT col, INT row, INT coldif,
- INT rowdif);
- VOID shift (INT state);
- VOID reduce (INT reduction);
- VOID printsheet (VOID);
- VOID clearsheet (VOID);
- VOID formatcells (VOID);
- VOID insertcol (INT col);
- VOID deletecol (INT col);
- VOID setcolwidth (INT col);
- VOID insertrow (INT row);
- VOID deleterow (INT row);
- VOID textstring (LPSTR instring, LPSTR outstring,
- INT col, INT fvalue, INT formatting);
- VOID valuestring (CELLPTR cellptr, DOUBLE value,
- LPSTR vstring, INT col, INT fvalue, LPINT color,
- INT formatting);
- DOUBLE cellvalue (INT col, INT row);
- INT isfunc (LPSTR s);
- VOID addformula (VOID);
- UINT APIENTRY hookproc1 (HWND hdlg, UINT uimsg,
- WPARAM wparam, LPARAM lparam);
- UINT APIENTRY hookproc2 (HWND hdlg, UINT uimsg,
- WPARAM wparam, LPARAM lparam);
- INT copys (VOID);
- VOID pastes (VOID);
- INT pagerows (INT row, INT toppage, INT border);
- INT pagecols (INT col, INT border, INT columns);
-
- INT leftcol, rightcol, toprow, bottomrow, curcol, inpt,
- currow, lastcol, lastrow, curcolb, currowb, i, j,
- leftcolb, toprowb, loading, stacktop, tokentype,
- error, counter, col, row, oldleftcol, oldrightcol,
- size, allocated, n, reallastcol, reallastrow, ignorep,
- overwrite, cl, rw, rows, len, firstcol, columns,
- counter1, counter2, counter3, border, toppage, lcol,
- lrow, dummy, printed, oldlastcol, width, col1, col2,
- row1, temp, newformat, rowc, color, pos, insert, row2,
- good, first, oldcol, oldrow, numlen, decimal, maxlen,
- fcol, frow, lrowdif, spaces1, spaces2, total, attrib,
- newcol, formatvalue, ch, changed, formdisplay, ofd,
- autocalc, stop, correctkey, success, isformula,
- accepted, ii, jj, coldif, rowdif, ocurcol, ocurrow;
- CHAR str [MAXINPUT + 1], filename [MAX_PATH],
- colstr [MAXINPUT + 1], data [10], pfilename [10],
- numstring [MAXINPUT + 1], copy [MAXINPUT + 1],
- newformula [MAXINPUT + 1], just [10], ljust [10],
- rjust [10], tmp [MAXINPUT + 1], cstr [MAXINPUT + 1],
- stri [MAXINPUT + 1], ffstr [MAXINPUT + 1];
- UCHAR format [MAXCOLS] [MAXROWS], colwidth [MAXCOLS],
- colstart [SCREENCOLS], oldcolstart [SCREENCOLS];
- LPSTR input, ftext, fstr, s, start, clstart,
- rowstart, curpos, fstring, p, *filepart;
- DWORD shortcursor = 0x0607, tallcursor = 0x0507,
- nocursor = 0x2000, c, ac, outc, written, fsize;
- DOUBLE value;
- CELLPTR cell [MAXCOLS] [MAXROWS], curcell, cellptr1,
- cellptr2, cellptr;
- TOKENREC stack [PARSERSTACKSIZE], curtoken, token1,
- token2;
- va_list arg_ptr;
- MEMORYSTATUS memstatus;
- CONSOLE_CURSOR_INFO curinfo;
- INPUT_RECORD inp;
- HANDLE si, so, hfile;
- COORD coord;
- CHAR_INFO charinfo;
- SMALL_RECT R;
- OPENFILENAME ofn;
- HGLOBAL ctext;
- HWND hwndmain;
-
- //checks whether pressed key have to be processed
- BOOL iscorrectkey (VOID)
- {
- c = inp.Event.KeyEvent.wVirtualKeyCode;
- correctkey = FALSE;
- if (inp.Event.KeyEvent.bKeyDown == TRUE && c != 16)
- {
- if (inp.Event.KeyEvent.uChar.AsciiChar != 0)
- correctkey = TRUE;
- else if ((c >= 33 && c <= 40) || c == 110 ||
- c == 45 || c == 120 || c == 113 || c == 67 ||
- c == 86 || c == 115 || c == 191)
- correctkey = TRUE;
- }
- return (correctkey);
- }
-
- //gets key and removes input message
- INT getkey (VOID)
- {
- do
- ReadConsoleInput (si, &inp, 1, (LPDWORD) &written);
- while (iscorrectkey () == FALSE);
- c = inp.Event.KeyEvent.wVirtualKeyCode;
- ac = inp.Event.KeyEvent.uChar.AsciiChar;
- outc = 0;
- if (ac != 0 && c != 110 && c != 67 && c != 86 &&
- c != 9)
- return (ac);
- if (c == 36) outc = HOMEKEY;
- if (c == 35) outc = ENDKEY;
- if (c == 38) outc = UPKEY;
- if (c == 40) outc = DOWNKEY;
- if (c == 33) outc = PGUPKEY;
- if (c == 34) outc = PGDNKEY;
- if (c == 37) outc = LEFTKEY;
- if (c == 110) outc = DELKEY;
- if (c == 45) outc = INSKEY;
- if (c == 39) outc = RIGHTKEY;
- if (c == 120) outc = F9;
- if (c == 113) outc = F2;
- if (c == 9) outc = TABKEY;
- if (c == 191) outc = '^';
- if (c == 115 &&
- ((inp.Event.KeyEvent.dwControlKeyState |
- RIGHT_ALT_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState ||
- (inp.Event.KeyEvent.dwControlKeyState |
- LEFT_ALT_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState))
- outc = ALTF4;
- else if (c == 115)
- outc = F4;
- if (c == 67 &&
- ((inp.Event.KeyEvent.dwControlKeyState |
- RIGHT_CTRL_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState ||
- (inp.Event.KeyEvent.dwControlKeyState |
- LEFT_CTRL_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState))
- outc = CTRLC;
- else if (c == 67)
- outc = ac;
- if (c == 86 &&
- ((inp.Event.KeyEvent.dwControlKeyState |
- RIGHT_CTRL_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState ||
- (inp.Event.KeyEvent.dwControlKeyState |
- LEFT_CTRL_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState))
- outc = CTRLV;
- else if (c == 86)
- outc = ac;
- if (c == 37 &&
- ((inp.Event.KeyEvent.dwControlKeyState |
- RIGHT_CTRL_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState ||
- (inp.Event.KeyEvent.dwControlKeyState |
- LEFT_CTRL_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState))
- outc = CTRLLEFTKEY;
- if (c == 39 &&
- ((inp.Event.KeyEvent.dwControlKeyState |
- RIGHT_CTRL_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState ||
- (inp.Event.KeyEvent.dwControlKeyState |
- LEFT_CTRL_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState))
- outc = CTRLRIGHTKEY;
- if (c == 37 &&
- (inp.Event.KeyEvent.dwControlKeyState |
- SHIFT_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState)
- outc = SHIFTLEFTKEY;
- if (c == 39 &&
- (inp.Event.KeyEvent.dwControlKeyState |
- SHIFT_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState)
- outc = SHIFTRIGHTKEY;
- if (c == 38 &&
- (inp.Event.KeyEvent.dwControlKeyState |
- SHIFT_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState)
- outc = SHIFTUPKEY;
- if (c == 40 &&
- (inp.Event.KeyEvent.dwControlKeyState |
- SHIFT_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState)
- outc = SHIFTDOWNKEY;
- if (c == 35 &&
- (inp.Event.KeyEvent.dwControlKeyState |
- SHIFT_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState)
- outc = SHIFTENDKEY;
- if (c == 120 &&
- (inp.Event.KeyEvent.dwControlKeyState |
- SHIFT_PRESSED) ==
- inp.Event.KeyEvent.dwControlKeyState)
- outc = SHIFTF9;
- return (outc);
- }
-
- //prints string on console
- VOID writef (INT col, INT row, INT color, INT width,
- LPSTR format, ...)
- {
- va_start (arg_ptr, format);
- wvsprintf (tmp, format, arg_ptr);
- tmp [width] = 0;
- if ((n = lstrlen (tmp)) < width)
- FillMemory (&tmp [n], width - n, ' ');
- for (i = 0; i <= lstrlen (tmp); i++)
- if (tmp [i] == (CHAR) 228 || tmp [i] == (CHAR) 229)
- tmp [i] = 147;
- SetConsoleTextAttribute (so, color);
- SetConsoleCursorPosition (so,
- (COORD) {col - 1, row - 1});
- WriteConsole (so, tmp, lstrlen (tmp), &written, NULL);
- }
-
- //moves a rectangular area of the screen
- VOID movetext (INT left, INT top, INT right, INT bottom,
- INT newleft, INT newtop)
- {
- R.Left = left - 1;
- R.Top = top - 1;
- R.Right = right - 1;
- R.Bottom = bottom - 1;
- ScrollConsoleScreenBuffer (so, &R, NULL,
- (COORD) {newleft - 1, newtop - 1}, &charinfo);
- }
-
- //sets small rectangle
- VOID setrect (INT left, INT top, INT right, INT bottom)
- {
- R.Left = left;
- R.Top = top;
- R.Right = right;
- R.Bottom = bottom;
- }
-
- //scrolls an area of the screen
- VOID scroll (INT direction, INT lines, INT x1, INT y1,
- INT x2, INT y2, INT attrib)
- {
- if (lines == 0)
- setrect (x1, y1, x2, y2);
- else
- switch (direction)
- {
- case UP:
- movetext (x1, y1 + lines, x2, y2, x1, y1);
- setrect (x1, y2 - lines + 1, x2, y2);
- break;
-
- case DOWN:
- movetext (x1, y1, x2, y2 - lines, x1, y1 + lines);
- setrect (x1, y1, x2, y1 + lines - 1);
- break;
-
- case LEFT:
- movetext (x1 + lines, y1, x2, y2, x1, y1);
- setrect (x2 - lines + 1, y1, x2, y2);
- break;
-
- case RIGHT:
- movetext (x1, y1, x2 - lines, y2, x1 + lines, y1);
- setrect (x1, y1, x1 + lines - 1, y2);
- break;
- }
- coord.X = R.Left - 1;
- for (coord.Y = R.Top - 1; coord.Y <= R.Bottom - 1;
- coord.Y++)
- FillConsoleOutputAttribute
- (so, attrib, R.Right - R.Left + 1, coord, &written);
- for (coord.Y = R.Top - 1; coord.Y <= R.Bottom - 1;
- coord.Y++)
- FillConsoleOutputCharacter
- (so, ' ', R.Right - R.Left + 1, coord, &written);
- }
-
- //creates output string for data in cell (col, row),
- //also returns the color of the cell
- LPSTR cellstring (INT col, INT row, LPINT color,
- INT formatting)
- {
- cellptr = cell [col] [row];
- if (cellptr == NULL)
- {
- if (!formatting || format [col] [row] < OVERWRITE)
- {
- sprintf (cstr, "%*s", colwidth [col], "");
- *color = BLANKCOLOR;
- }
- else
- {
- newcol = col;
- while (cell [--newcol] [row] == NULL);
- p = cell [newcol] [row]->v.text;
- while (newcol < col) p += colwidth [newcol++];
- strncpy (tmp, p, colwidth [col]);
- tmp [colwidth [col]] = 0;
- sprintf (cstr, "%s%*s", tmp, colwidth [col] -
- lstrlen (tmp), "");
- *color = TEXTCOLOR;
- }
- }
- else
- {
- formatvalue = format [col] [row];
- switch (cellptr->attrib)
- {
- case TEXTCELL:
- textstring (cellptr->v.text, cstr, col,
- formatvalue, formatting);
- *color = TEXTCOLOR;
- break;
-
- case FORMULA:
- if (formdisplay)
- {
- textstring (cellptr->v.f.formula, cstr, col,
- formatvalue, formatting);
- *color = FORMULACOLOR;
- break;
- }
- else
- value = cellptr->v.f.fvalue;
-
- case VALUE :
- if (cellptr->attrib == VALUE)
- value = cellptr->v.value;
- valuestring (cellptr, value, cstr, col,
- formatvalue, color, formatting);
- break;
- }
- }
- return (cstr);
- }
-
- //sets the string representation of a value
- VOID valuestring (CELLPTR cellptr, DOUBLE value,
- LPSTR vstring, INT col, INT fvalue, LPINT color,
- INT formatting)
- {
- if (value == HUGE_VAL)
- {
- strcpy (vstring, MSGERROR);
- *color = ERRORCOLOR;
- }
- else
- {
- if (formatting)
- {
- sprintf (vstring, "%1.*f", fvalue & 15,
- cellptr->v.value);
- if (fvalue & COMMAS)
- {
- pos = strcspn (vstring, ".");
- while (pos > 3)
- {
- pos -= 3;
- if (vstring [pos - 1] != '-')
- {
- MoveMemory (&vstring[pos + 1], &vstring[pos],
- lstrlen (vstring) - pos + 1);
- vstring [pos] = ',';
- }
- }
- }
- if (fvalue & DOLLAR)
- {
- if (vstring [0] == '-')
- {
- fstring = " $";
- width = colwidth [col] - 2;
- }
- else
- {
- fstring = " $ ";
- width = colwidth [col] - 3;
- }
- }
- else
- {
- fstring = "";
- width = colwidth [col];
- }
- strcpy (str, vstring);
- if (fvalue & RJUSTIFY)
- {
- if (lstrlen (vstring) > width)
- vstring [width] = 0;
- else
- sprintf (vstring, "%*s", width, str);
- }
- else
- sprintf (vstring, "%-*s", width, s);
- MoveMemory (&vstring [lstrlen (fstring)], vstring,
- lstrlen (vstring) + 1);
- strncpy (vstring, fstring, lstrlen (fstring));
- }
- else
- sprintf (vstring, "%.*f", MAXPLACES, value);
- *color = VALUECOLOR;
- }
- }
-
- //sets the string representation of text
- VOID textstring (LPSTR instring, LPSTR outstring,
- INT col, INT fvalue, INT formatting)
- {
- lstrcpy (ljust, "%-*s");
- lstrcpy (rjust, "%*s");
- if ((fvalue & RJUSTIFY) && formatting)
- lstrcpy (just, rjust);
- else
- lstrcpy (just, ljust);
- sprintf (outstring, just, colwidth [col], instring);
- if (formatting) outstring [colwidth [col]] = 0;
- }
-
- //sets overwrite flag on cells starting at (col + 1,
- //row), returns number of column after last column set
- INT setoflags (INT col, INT row, INT display)
- {
- len = lstrlen (cell [col] [row]->v.text) -
- colwidth [col];
- while (++col < MAXCOLS && len > 0 &&
- cell [col] [row] == NULL)
- {
- format [col] [row] |= OVERWRITE;
- len -= colwidth [col];
- if (display && col >= leftcol && col <= rightcol)
- displaycell (col, row, NOHIGHLIGHT, NOUPDATE);
- }
- return (col);
- }
-
- //moves back from col to last TEXTCELL and updates flags
- VOID updateoflags (INT col, INT row, INT display)
- {
- while (cell [col] [row] == NULL && col-- > 0);
- if (col >= 0)
- if (cell [col] [row] != NULL &&
- cell [col] [row]->attrib == TEXTCELL)
- setoflags (col, row, display);
- }
-
- //clears overwrite flag on cells starting at (col, row)
- VOID clearoflags (INT col, INT row, INT display)
- {
- while (format [col] [row] >= OVERWRITE &&
- col < MAXCOLS && cell [col] [row] == NULL)
- {
- format [col] [row] &= ~OVERWRITE;
- if (display && col >= leftcol && col <= rightcol)
- displaycell (col, row, NOHIGHLIGHT, NOUPDATE);
- col++;
- }
- }
-
- //acts on a particular input
- VOID act (LPSTR s)
- {
- deletecell (curcol, currow, UPDATE);
- value = parse (s, &attrib);
- switch (attrib)
- {
- case TEXTCELL:
- allocated = alloctext (curcol, currow, s);
- if (allocated)
- displaycell (curcol, currow, NOHIGHLIGHT,
- NOUPDATE);
- break;
-
- case VALUE:
- allocated = allocvalue (curcol, currow, value);
- break;
-
- case FORMULA:
- allocated = allocformula (curcol, currow, s, value);
- break;
- }
- if (allocated)
- {
- format [curcol] [currow] &= ~OVERWRITE;
- clearoflags (curcol + 1, currow, UPDATE);
- if (attrib == TEXTCELL)
- setoflags (curcol, currow, UPDATE);
- if (curcol > lastcol) lastcol = curcol;
- if (currow > lastrow) lastrow = currow;
- if (autocalc) recalc ();
- }
- else
- errormsg (MSGLOMEM);
- printfreemem ();
- }
-
- //sets value of lastrow based on the current value
- VOID setlastrow (VOID)
- {
- for (row = lastrow; row >= 0; row--)
- for (col = 0; col <= lastcol; col++)
- if (cell [col] [row] != NULL)
- {
- lastrow = row;
- return;
- }
- lastrow = 0;
- }
-
- //sets value of lastcol based on the current value
- VOID setlastcol (VOID)
- {
- for (col = lastcol; col >= 0; col--)
- for (row = 0; row <= lastrow; row++)
- if (cell [col] [row] != NULL)
- {
- lastcol = col;
- return;
- }
- lastcol = 0;
- }
-
- //figures out value of bottomrow based on value of toprow
- VOID setbottomrow (VOID)
- {
- if (toprow + SCREENROWS > MAXROWS)
- toprow = MAXROWS - 20;
- bottomrow = toprow + 19;
- for (row = 0; row < SCREENROWS; row++)
- writef (1, row + 3, HEADERCOLOR, LEFTMARGIN, "%-d",
- row + toprow + 1);
- }
-
- //sets value of rightcol based on the value of leftcol
- VOID setrightcol (VOID)
- {
- total = LEFTMARGIN;
- col = 0;
- do
- {
- colstart [col] = total;
- total += colwidth [leftcol + col++];
- }
- while (total <= 80 && leftcol + col <= MAXCOLS);
- rightcol = leftcol + col - 2;
- printcol ();
- }
-
- //sets value of leftcol based on the value of rightcol
- VOID setleftcol (VOID)
- {
- total = 80;
- col = 0;
- while (total >= LEFTMARGIN && rightcol - col >= 0)
- {
- colstart [SCREENCOLS - col - 1] =
- total - colwidth [rightcol - col];
- total -= colwidth [rightcol - col++];
- }
- if (total >= LEFTMARGIN) col++;
- MoveMemory (colstart, &colstart [SCREENCOLS - col + 1],
- col - 1);
- leftcol = rightcol - col + 2;
- total = colstart [0] - LEFTMARGIN;
- if (total != 0)
- for (col = leftcol; col <= rightcol; col++)
- colstart [col - leftcol] -= total;
- printcol();
- }
-
- //changes a column to a centered string
- VOID centercolstring (INT col, LPSTR colstr)
- {
- colstring (col, str);
- spaces1 = (colwidth [col] - lstrlen (str)) >> 1;
- spaces2 = colwidth [col] - lstrlen (str) - spaces1;
- sprintf (colstr, "%*s%s%*s", spaces1, "", str,
- spaces2, "");
- }
-
- //changes a column number to a string
- VOID colstring (INT col, LPSTR colstr)
- {
- FillMemory (colstr, 3, 0);
- if (col < 26)
- colstr [0] = col + 'A';
- else
- {
- colstr [0] = (col / 26) - 1 + 'A';
- colstr [1] = (col % 26) + 'A';
- }
- }
-
- //fix copied formula
- VOID fixformula2 (INT col, INT row, INT acoldif,
- INT arowdif)
- {
- coldif = acoldif;
- rowdif = arowdif;
- curpos = newformula;
- cellptr = cell [col] [row];
- strcpy (newformula, cellptr->v.f.formula);
- while (*curpos != 0)
- {
- if (formulastart (&curpos, &fcol, &frow))
- {
- if (fcol + acoldif < 0) coldif = MAXCOLS + acoldif;
- if (frow + arowdif < 0) rowdif = MAXROWS + arowdif;
- if (fcol + acoldif >= MAXCOLS)
- coldif = acoldif - MAXCOLS;
- if (frow + arowdif >= MAXROWS)
- rowdif = arowdif - MAXROWS;
- rowstart = curpos - rowwidth (frow);
- clstart = rowstart - ((fcol > 25) ? 2 : 1);
- if (fcol <= 25 && fcol + coldif > 25)
- {
- if (lstrlen (newformula) == MAXINPUT)
- {
- deletecell (col, row, NOUPDATE);
- alloctext (col, row, newformula);
- return;
- }
- MoveMemory (clstart + 1, clstart,
- lstrlen (clstart) + 1);
- curpos++;
- rowstart++;
- }
- if (fcol > 25 && fcol + coldif <= 25)
- {
- MoveMemory (clstart, clstart + 1,
- lstrlen (clstart) + 1);
- curpos--;
- rowstart--;
- }
-
- lrowdif = rowwidth (frow + rowdif) -
- rowwidth (frow);
- if (lrowdif > 0)
- {
- if (lstrlen (newformula) + lrowdif > MAXINPUT)
- {
- deletecell (col, row, NOUPDATE);
- alloctext (col, row, newformula);
- return;
- }
- MoveMemory (rowstart + lrowdif, rowstart,
- lstrlen (rowstart) + 1);
- curpos = curpos + lrowdif;
- }
- if (lrowdif < 0)
- {
- MoveMemory (rowstart, rowstart - lrowdif,
- lstrlen (rowstart) + 1);
- curpos = curpos + lrowdif;
- }
-
- colstring (fcol + coldif, ffstr);
- MoveMemory (clstart, ffstr, lstrlen (ffstr));
- sprintf (ffstr, "%d", frow + rowdif + 1);
- MoveMemory (rowstart, ffstr, lstrlen (ffstr));
- }
- else
- curpos++;
- }
- strcpy (cellptr->v.f.formula, newformula);
- }
-
- //modifies column or row designations of the formula
- VOID fixformula (INT col, INT row, INT action, INT place)
- {
- s = str;
- curpos = newformula;
- cellptr = cell [col] [row];
- strcpy (newformula, cellptr->v.f.formula);
- while (*curpos != 0)
- {
- if (formulastart (&curpos, &fcol, &frow))
- {
- rowstart = curpos - rowwidth (frow);
- clstart = rowstart - ((fcol > 25) ? 2 : 1);
- switch (action)
- {
- case COLADD:
- if (fcol < place) break;
- if (fcol == 25)
- {
- if (lstrlen (newformula) == MAXINPUT)
- {
- deletecell (col, row, NOUPDATE);
- alloctext (col, row, newformula);
- return;
- }
- MoveMemory (clstart + 1, clstart,
- lstrlen (clstart) + 1);
- }
- colstring (fcol + 1, s);
- MoveMemory (clstart, s, lstrlen (s));
- break;
-
- case ROWADD:
- if (frow < place) break;
- if (rowwidth (frow + 1) != rowwidth (frow))
- {
- if (lstrlen (newformula) == MAXINPUT)
- {
- deletecell (col, row, NOUPDATE);
- alloctext (col, row, newformula);
- return;
- }
- MoveMemory (rowstart + 1, rowstart,
- lstrlen (rowstart) + 1);
- }
- sprintf (s, "%d", frow + 2);
- MoveMemory (rowstart, s, lstrlen (s));
- break;
-
- case COLDEL:
- if (fcol <= place) break;
- if (fcol == 26)
- MoveMemory (clstart, clstart + 1,
- lstrlen (clstart) + 1);
- colstring (fcol - 1, s);
- MoveMemory (clstart, s, lstrlen (s));
- break;
-
- case ROWDEL:
- if (frow <= place) break;
- if (rowwidth (frow) != rowwidth (frow - 1))
- MoveMemory (rowstart, rowstart + 1,
- lstrlen (rowstart) + 1);
- sprintf (s, "%d", frow);
- MoveMemory (rowstart, s, lstrlen (s));
- break;
- }
- }
- else
- curpos++;
- }
- if (lstrlen (newformula) !=
- lstrlen (cellptr->v.f.formula))
- {
- value = cellptr->v.f.fvalue;
- deletecell (col, row, NOUPDATE);
- allocformula (col, row, newformula, value);
- }
- else
- strcpy (cellptr->v.f.formula, newformula);
- }
-
- VOID errormsg (LPSTR s)
- {
- writef (1, 25, ERRORCOLOR, 79, "%s %s", s,
- MSGKEYPRESS);
- SetConsoleCursorPosition (so, (COORD)
- {lstrlen (s) + lstrlen (MSGKEYPRESS) + 2, 24});
- getkey ();
- SetConsoleCursorPosition (so, (COORD) {0, 24});
- writef (1, 25, TEXTCOLOR, 79, "");
- }
-
- //returns TRUE if the string is the start of a formula,
- //also returns the column and row of the formula
- int formulastart (char **input, int *col, int *row)
- {
- maxlen = rowwidth (MAXROWS);
- if (!IsCharAlpha (**input)) return (FALSE);
- *col = *((*input)++) - 'A';
- if (IsCharAlpha (**input))
- {
- *col *= 26;
- *col += *((*input)++) - 'A' + 26;
- }
- if (*col >= MAXCOLS) return (FALSE);
- start = *input;
- for (len = 0; len < maxlen; len++)
- {
- if (**input < '0' || **input > '9') break;
- (*input)++;
- }
- if (len == 0) return (FALSE);
- strncpy (numstring, start, len);
- numstring [len] = 0;
- *row = atoi (numstring) - 1;
- if (*row >= MAXROWS || *row == -1) return (FALSE);
- return (TRUE);
- }
-
- //returns the width in spaces of row
- INT rowwidth (INT row)
- {
- return ((row == 0) ? 1 : (INT) log10 (row + 1) + 1);
- }
-
- VOID printfreemem (VOID)
- {
- memstatus.dwLength = sizeof (MEMORYSTATUS);
- GlobalMemoryStatus (&memstatus);
- writef (lstrlen (MSGMEMORY) + 2, 1, MEMORYCOLOR, 10,
- "%lu", memstatus.dwAvailPhys);
- }
-
- VOID deletecell (INT col, INT row, INT display)
- {
- cellptr = cell [col] [row];
- if (cellptr == NULL) return;
- switch (cellptr->attrib)
- {
- case TEXTCELL:
- clearoflags (col + 1, row, display);
- break;
-
- case VALUE: break;
- case FORMULA: break;
- }
- format [col] [row] &= ~OVERWRITE;
- GlobalFree (cell [col] [row]);
- cell [col] [row] = NULL;
- if (col == lastcol) setlastcol ();
- if (row == lastrow) setlastrow ();
- updateoflags (col, row, display);
- changed = TRUE;
- }
-
- //allocates space for a formula cell
- INT allocformula (INT col, INT row, LPSTR s, DOUBLE amt)
- {
- cellptr = (CELLPTR) GlobalAlloc
- (GMEM_FIXED, sizeof (CELLREC));
- if (cellptr == NULL) return (FALSE);
- cellptr->attrib = FORMULA;
- strcpy (cellptr->v.f.formula, s);
- cellptr->v.f.fvalue = amt;
- cell [col] [row] = cellptr;
- return (TRUE);
- }
-
- //allocates space for a value cell
- INT allocvalue (INT col, INT row, DOUBLE amt)
- {
- cellptr = (CELLPTR) GlobalAlloc
- (GMEM_FIXED, sizeof (CELLREC));
- if (cellptr == NULL) return (FALSE);
- cellptr->attrib = VALUE;
- cellptr->v.value = amt;
- cell [col] [row] = cellptr;
- return (TRUE);
- }
-
- //allocates space for a text cell
- INT alloctext (INT col, INT row, LPSTR s)
- {
- cellptr = (CELLPTR) GlobalAlloc
- (GMEM_FIXED, sizeof (CELLREC));
- if (cellptr == NULL) return (FALSE);
- cellptr->attrib = TEXTCELL;
- strcpy (cellptr->v.text, s);
- cell [col] [row] = cellptr;
- return (TRUE);
- }
-
- //completes a reduction
- VOID reduce (INT reduction)
- {
- switch (reduction)
- {
- case RPLUS:
- token1 = stack [stacktop--];
- stack [stacktop--];
- token2 = stack [stacktop--];
- curtoken.x.value = token1.x.value + token2.x.value;
- break;
-
- case RMINUS:
- token1 = stack [stacktop--];
- stack [stacktop--];
- token2 = stack [stacktop--];
- curtoken.x.value = token2.x.value - token1.x.value;
- break;
-
- case RTIMES:
- token1 = stack [stacktop--];
- stack [stacktop--];
- token2 = stack [stacktop--];
- curtoken.x.value = token1.x.value * token2.x.value;
- break;
-
- case RDIVIDE:
- token1 = stack [stacktop--];
- stack [stacktop--];
- token2 = stack [stacktop--];
- if (token1.x.value == 0)
- curtoken.x.value = HUGE_VAL;
- else
- curtoken.x.value = token2.x.value /
- token1.x.value;
- break;
-
- case RPOW:
- token1 = stack [stacktop--];
- stack [stacktop--];
- token2 = stack [stacktop--];
- curtoken.x.value = pow (token2.x.value,
- token1.x.value);
- break;
-
- case RNEGATE:
- token1 = stack [stacktop--];
- stack [stacktop--];
- curtoken.x.value = -token1.x.value;
- break;
-
- case RSUM:
- token1 = stack [stacktop--];
- stack [stacktop--];
- token2 = stack [stacktop--];
- curtoken.x.value = 0;
- if (token1.x.c.row == token2.x.c.row)
- {
- if (token1.x.c.col < token2.x.c.col)
- error = TRUE;
- else
- for (counter = token2.x.c.col;
- counter <= token1.x.c.col; counter++)
- curtoken.x.value += cellvalue (counter,
- token1.x.c.row);
- }
- else if (token1.x.c.col == token2.x.c.col)
- {
- if (token1.x.c.row < token2.x.c.row)
- error = TRUE;
- else
- for (counter = token2.x.c.row;
- counter <= token1.x.c.row; counter++)
- curtoken.x.value +=
- cellvalue (token1.x.c.col, counter);
- }
- else
- error = TRUE;
- break;
-
- case RCELLVALUE:
- curtoken = stack [stacktop--];
- curtoken.x.value = cellvalue (curtoken.x.c.col,
- curtoken.x.c.row);
- break;
-
- case RCPAREN:
- stack [stacktop--];
- curtoken = stack [stacktop--];
- stack [stacktop--];
- break;
-
- case RFUNC:
- stack [stacktop--];
- curtoken = stack [stacktop--];
- stack [stacktop--];
- token1 = stack [stacktop--];
- if (strcmp (token1.x.funcname, "ABS") == 0)
- curtoken.x.value = fabs (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "ACOS") == 0)
- curtoken.x.value = acos (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "ASIN") == 0)
- curtoken.x.value = asin (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "ATAN") == 0)
- curtoken.x.value = atan (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "COSH") == 0)
- curtoken.x.value = cosh (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "COS") == 0)
- curtoken.x.value = cos (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "EXP") == 0)
- curtoken.x.value = exp (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "LOG10") == 0)
- curtoken.x.value = log10 (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "LOG") == 0)
- curtoken.x.value = log (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "ROUND") == 0)
- curtoken.x.value = (INT) (curtoken.x.value + 0.5);
- else if (strcmp (token1.x.funcname, "POW10") == 0)
- curtoken.x.value = pow (10, curtoken.x.value);
- else if (strcmp (token1.x.funcname, "SINH") == 0)
- curtoken.x.value = sinh (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "SIN") == 0)
- curtoken.x.value = sin (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "SQRT") == 0)
- curtoken.x.value = sqrt (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "SQR") == 0)
- curtoken.x.value *= curtoken.x.value;
- else if (strcmp (token1.x.funcname, "TANH") == 0)
- curtoken.x.value = tanh (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "TAN") == 0)
- curtoken.x.value = tan (curtoken.x.value);
- else if (strcmp (token1.x.funcname, "TRUNC") == 0)
- curtoken.x.value = (INT) curtoken.x.value;
- break;
-
- case RFIRSTTIMES: case RFIRSTPOW: case RFIRSTNEGATE:
- case RFIRSTSUM: case RFIRSTFUNC: case RNUM:
- curtoken = stack [stacktop--];
- break;
- }
-
- if (reduction <= 3) //RPLUS, RMINUS, RFIRSTTIMES
- switch (stack [stacktop].state)
- {
- case SFIRST: curtoken.state = SFIRSTPLUS; break;
- case SOPAREN: curtoken.state = SOPARENPLUS; break;
- case SFOPAREN: curtoken.state = SFOPARENPLUS; break;
- }
- else if (reduction <= 6) //RTIMES, RDIVIDE, RFIRSTPOW
- switch (stack [stacktop].state)
- {
- case SFIRST: case SOPAREN: case SFOPAREN:
- curtoken.state = SFIRSTTIMES;
- break;
-
- case SPLUS: curtoken.state = SPLUSTIMES; break;
- case SMINUS: curtoken.state = SMINUSTIMES; break;
- }
- else if (reduction <= 8) //RPOW, RFIRSTNEGATE
- switch (stack [stacktop].state)
- {
- case SFIRST: case SOPAREN: case SPLUS: case SMINUS:
- case SFOPAREN:
- curtoken.state = SFIRSTPOW;
- break;
-
- case STIMES: curtoken.state = SDOTIMES; break;
- case SDIVIDE: curtoken.state = SDODIVIDE; break;
- case SPOW: curtoken.state = SDOPOW; break;
- }
- else if (reduction <= 10) //RNEGATE, RFIRSTSUM
- switch (stack [stacktop].state)
- {
- case SFIRST: case SOPAREN: case SPLUS: case SMINUS:
- case STIMES: case SDIVIDE: case SPOW:
- case SFOPAREN:
- curtoken.state = SFIRSTNEGATE;
- break;
- }
- else if (reduction <= 12) //RSUM, RFIRSTFUNC
- switch (stack [stacktop].state)
- {
- case SFIRST: case SOPAREN: case SPLUS: case SMINUS:
- case STIMES: case SDIVIDE: case SPOW:
- case SFOPAREN:
- curtoken.state = SFIRSTSUM;
- break;
-
- case SNEGATE: curtoken.state = SDONEGATE;
- }
- else //RCELLVALUE, RCPAREN, RNUM, RFUNC
- switch (stack [stacktop].state)
- {
- case SFIRST: case SNEGATE: case SOPAREN: case SPLUS:
- case SMINUS: case STIMES: case SDIVIDE:
- case SPOW: case SFOPAREN:
- curtoken.state = SFIRSTFUNC;
- break;
-
- default: curtoken.state = SERROR; break;
- }
-
- if (stacktop == PARSERSTACKSIZE - 1)
- {
- errormsg (MSGSTACKERROR);
- error = TRUE;
- }
- else
- stack [++stacktop] = curtoken;
- }
-
- //shifts token onto the stack
- VOID shift (INT state)
- {
- curtoken.state = state;
- if (stacktop == PARSERSTACKSIZE - 1)
- {
- errormsg (MSGSTACKERROR);
- error = TRUE;
- }
- else
- stack [++stacktop] = curtoken;
-
- while (*input == ' ') input++;
- if (*input == 0)
- {
- tokentype = EOLN;
- return;
- }
- if (strchr ("0123456789.", *input))
- {
- start = input;
- len = 0;
- decimal = FALSE;
- while ((*input >= '0' &&
- *input <= '9') || (*input == '.' &&
- !decimal))
- {
- if (*input == '.') decimal = TRUE;
- input++;
- len++;
- }
- if (len == 1 && start [0] == '.')
- {
- tokentype = BAD;
- return;
- }
- if (*input == 'E')
- {
- input++;
- len++;
- if (strchr ("+-", *input) != NULL)
- {
- input++;
- len++;
- }
- numlen = 0;
- while (*input >= '0' &&
- *input <= '9' && ++numlen <= 3)
- {
- input++;
- len++;
- }
- }
- strncpy (numstring, start, len);
- numstring [len] = 0;
- curtoken.x.value = atof (numstring);
- if (*_errno () == 34)
- {
- tokentype = BAD;
- return;
- }
- tokentype = NUM;
- return;
- }
- else if (IsCharAlpha (*input))
- {
- if (isfunc ("ABS") || isfunc ("ACOS") ||
- isfunc ("ASIN") || isfunc ("ATAN") ||
- isfunc ("COSH") || isfunc ("COS") ||
- isfunc ("EXP") || isfunc ("LOG10") ||
- isfunc ("LOG") || isfunc ("POW10") ||
- isfunc ("ROUND") || isfunc ("SINH") ||
- isfunc ("SIN") || isfunc ("SQRT") ||
- isfunc ("SQR") || isfunc ("TANH") ||
- isfunc ("TAN") || isfunc ("TRUNC"))
- {
- tokentype = FUNC;
- return;
- }
- if (formulastart (&input, &curtoken.x.c.col,
- &curtoken.x.c.row))
- {
- isformula = TRUE;
- tokentype = CELL;
- return;
- }
- else
- {
- tokentype = BAD;
- return;
- }
- }
- else
- switch (*(input++))
- {
- case '+': tokentype = PLUS; return;
- case '-': tokentype = MINUS; return;
- case '*': tokentype = TIMES; return;
- case '/': tokentype = DIVIDE; return;
- case '^': tokentype = EXP; return;
- case ':': tokentype = COLON; return;
- case '(': tokentype = OPAREN; return;
- case ')': tokentype = CPAREN; return;
- default: tokentype = BAD; return;
- }
- }
-
- //parses string s, returns value of the evaluated string,
- //puts in att: TEXTCELL = 0, CONSTANT = 1, FORMULA = 2
- DOUBLE parse (LPSTR s, LPINT att)
- {
- accepted = FALSE;
- error = FALSE;
- isformula = FALSE;
- input = copy;
- strupr (strcpy (copy, s));
- stacktop = -1;
- curtoken.x.value = 0;
- shift (SFIRST);
- do
- {
- switch (stack [stacktop].state)
- {
- case SFIRST: case SOPAREN: case SPLUS: case SMINUS:
- case STIMES: case SDIVIDE: case SPOW:
- case SFOPAREN:
- if (tokentype == NUM)
- shift (SNUM);
- else if (tokentype == CELL)
- shift (SCELL);
- else if (tokentype == FUNC)
- shift (SFUNC);
- else if (tokentype == MINUS)
- shift (SNEGATE);
- else if (tokentype == OPAREN)
- shift (SOPAREN);
- else
- error = TRUE;
- break;
-
- case SFIRSTPLUS:
- if (tokentype == EOLN)
- accepted = TRUE;
- else if (tokentype == PLUS)
- shift (SPLUS);
- else if (tokentype == MINUS)
- shift (SMINUS);
- else
- error = TRUE;
- break;
-
- case SFIRSTTIMES:
- if (tokentype == TIMES)
- shift (STIMES);
- else if (tokentype == DIVIDE)
- shift (SDIVIDE);
- else
- reduce (RFIRSTTIMES);
- break;
-
- case SFIRSTPOW: reduce (RFIRSTPOW); break;
-
- case SFIRSTNEGATE:
- if (tokentype == EXP)
- shift (SPOW);
- else
- reduce (RFIRSTNEGATE);
- break;
-
- case SNEGATE:
- if (tokentype == NUM)
- shift (SNUM);
- else if (tokentype == CELL)
- shift (SCELL);
- else if (tokentype == FUNC)
- shift (SFUNC);
- else if (tokentype == OPAREN)
- shift (SOPAREN);
- else
- error = TRUE;
- break;
-
- case SFIRSTSUM: reduce (RFIRSTSUM); break;
-
- case SCELL:
- if (tokentype == COLON)
- shift (SCOLON);
- else
- reduce (RCELLVALUE);
- break;
-
- case SFIRSTFUNC: reduce (RFIRSTFUNC); break;
- case SNUM: reduce (RNUM); break;
-
- case SFUNC:
- if (tokentype == OPAREN)
- shift (SFOPAREN);
- else
- error = TRUE;
- break;
-
- case SDONEGATE: reduce (RNEGATE); break;
-
- case SCOLON:
- if (tokentype == CELL)
- shift (SDOSUM);
- else
- error = TRUE;
- break;
-
- case SOPARENPLUS:
- if (tokentype == PLUS)
- shift (SPLUS);
- else if (tokentype == MINUS)
- shift (SMINUS);
- else if (tokentype == CPAREN)
- shift (SCPAREN);
- else
- error = TRUE;
- break;
-
- case SPLUSTIMES:
- if (tokentype == TIMES)
- shift (STIMES);
- else if (tokentype == DIVIDE)
- shift (SDIVIDE);
- else
- reduce (RPLUS);
- break;
-
- case SMINUSTIMES:
- if (tokentype == TIMES)
- shift (STIMES);
- else if (tokentype == DIVIDE)
- shift (SDIVIDE);
- else
- reduce (RMINUS);
- break;
-
- case SDOTIMES: reduce (RTIMES); break;
- case SDODIVIDE: reduce (RDIVIDE); break;
- case SDOPOW: reduce (RPOW); break;
- case SDOSUM: reduce (RSUM); break;
- case SCPAREN: reduce (RCPAREN); break;
-
- case SFOPARENPLUS:
- if (tokentype == PLUS)
- shift (SPLUS);
- else if (tokentype == MINUS)
- shift (SMINUS);
- else if (tokentype == CPAREN)
- shift (SDOFUNC);
- else
- error = TRUE;
- break;
-
- case SDOFUNC: reduce (RFUNC); break;
- case SERROR: error = TRUE; break;
- }
- }
- while (!accepted && !error);
- if (error)
- {
- *att = TEXTCELL;
- return (0);
- }
- if (isformula)
- *att = FORMULA;
- else
- *att = VALUE;
- strcpy (s, copy);
- return (stack [stacktop].x.value);
- }
-
- //finds the value of a particular cell
- DOUBLE cellvalue (INT col, INT row)
- {
- if (cell [col] [row] == NULL) return (0);
- if (cell [col] [row]->attrib == TEXTCELL)
- return (HUGE_VAL);
- if (cell [col] [row]->attrib == FORMULA)
- return (cell [col] [row]->v.f.fvalue);
- return (cell [col] [row]->v.value);
- }
-
- //returns TRUE if the string is a legal function
- INT isfunc (LPSTR s)
- {
- len = lstrlen (s);
- if (strncmp (s, input, len) == 0)
- {
- strncpy (curtoken.x.funcname, input, len);
- curtoken.x.funcname [len] = 0;
- input += len;
- return (TRUE);
- }
- return (FALSE);
- }
-
- //gets yes or no answer, returns TRUE if ESC was pressed
- INT getyesno (LPINT yesno, LPSTR prompt)
- {
- writef (1, 24, PROMPTCOLOR, 80, prompt);
- setcursor (shortcursor);
- do
- {
- *yesno = (CHAR) CharUpper ((LPSTR) getkey ());
- if (*yesno == ESC)
- {
- setcursor (nocursor);
- return (FALSE);
- }
- }
- while (strchr ("YN", *yesno) == NULL);
- setcursor (nocursor);
- return (TRUE);
- }
-
- //reads cell name, returns FALSE if ESC was pressed
- INT getcell (LPINT col, LPINT row)
- {
- first = TRUE;
- good = FALSE;
- oldcol = *col;
- oldrow = *row;
- numlen = rowwidth (MAXROWS);
- data [0] = 0;
- do
- {
- if (!first) errormsg (MSGBADCELL);
- first = FALSE;
- input = data;
- if (!editstring (data, "", numlen + 2))
- {
- *col = oldcol;
- *row = oldrow;
- return (FALSE);
- }
- *col = (CHAR) CharUpper ((LPSTR) *(input++)) - 'A';
- if (IsCharAlpha (*input))
- {
- *col *= 26;
- *col += (CHAR) CharUpper ((LPSTR) *(input++)) -
- 'A' + 26;
- }
- if (*col >= MAXCOLS) continue;
- start = input;
- for (len = 0; len < numlen; len++)
- if (*(input++) < '0' || *(input++) > '9')
- {
- input--;
- break;
- }
- if (len == 0) continue;
- strncpy (numstring, start, len);
- numstring [len] = 0;
- *row = atoi (numstring) - 1;
- if ((*row >= MAXROWS) || (*row == -1) ||
- (*input != 0)) continue;
- good = TRUE;
- }
- while (!good);
- return (TRUE);
- }
-
- //reads in a positive integer from low to high
- INT getint (LPINT number, INT low, INT high)
- {
- good = FALSE;
- str [0] = 0;
- sprintf (cstr, MSGBADNUMBER, low, high);
- do
- {
- if (!editstring (str, "1234567890", 4))
- return (FALSE);
- i = atoi (str);
- if ((good = (i >= low && i <= high)) == 0)
- errormsg (cstr);
- }
- while (!good);
- *number = i;
- return (TRUE);
- }
-
- VOID setcursor (UINT shape)
- {
- if (shape == nocursor)
- curinfo.bVisible = FALSE;
- else
- curinfo.bVisible = TRUE;
- if (shape == shortcursor) curinfo.dwSize = 20;
- if (shape == tallcursor) curinfo.dwSize = 90;
- SetConsoleCursorInfo (so, &curinfo);
- }
-
- //allows the user to edit a string, returns TRUE if ESC
- //was not pressed, FALSE otherwise
- INT editstring (LPSTR s, LPSTR legal, INT maxlength)
- {
- len = lstrlen (s);
- pos = len;
- insert = TRUE;
- setcursor (shortcursor);
- do
- {
- writef (1, 25, TEXTCOLOR, 79, "%s", s);
- SetConsoleCursorPosition (so, (COORD) {pos, 24});
- switch (c = getkey())
- {
- case HOMEKEY: pos = 0; break;
- case ENDKEY: pos = len; break;
-
- case INSKEY:
- insert = !insert;
- if (insert)
- setcursor (shortcursor);
- else
- setcursor (tallcursor);
- break;
-
- case LEFTKEY: if (pos > 0) pos--; break;
- case RIGHTKEY: if (pos < len) pos++; break;
-
- case BS:
- if (pos > 0)
- {
- MoveMemory (&s [pos - 1], &s [pos],
- len - pos + 1);
- pos--;
- len--;
- }
- break;
-
- case DELKEY:
- if (pos < len)
- {
- MoveMemory (&s [pos], &s [pos + 1], len - pos);
- len--;
- }
- break;
-
- case CR: case TABKEY: case F4: case CTRLLEFTKEY:
- case CTRLRIGHTKEY: case PGUPKEY: case PGDNKEY:
- case CTRLC: case CTRLV: case ALTF4: case F2:
- case SHIFTUPKEY: case SHIFTDOWNKEY: case SHIFTF9:
- case SHIFTLEFTKEY: case SHIFTRIGHTKEY: case F9:
- break;
-
- case UPKEY: c = CR; break;
- case DOWNKEY: c = CR; break;
- case ESC: len = 0; break;
-
- default:
- if ((legal [0] == 0 || strchr (legal, c) != NULL) &&
- len < maxlength)
- {
- if (insert)
- {
- memmove (&s [pos + 1], &s [pos], len -
- pos + 1);
- len++;
- }
- else
- if (pos >= len) len++;
- s [pos++] = c;
- }
- break;
- }
- s [len] = 0;
- }
- while (c != CR && c != ESC);
- scroll (UP, 0, 1, 25, 80, 25, TEXTCOLOR);
- SetConsoleCursorPosition (so, (COORD) {0, 24});
- setcursor (shortcursor);
- setcursor (nocursor);
- return (c != ESC);
- }
-
- //displays the type of cell and what is in it
- VOID showcelltype (VOID)
- {
- formdisplay = !formdisplay;
- s = cellstring (curcol, currow, &color, NOFORMAT);
- colstring (curcol, colstr);
- if (curcell == NULL)
- writef (1, 23, CELLTYPECOLOR, 80, "%s%d %s", colstr,
- currow + 1, MSGEMPTY);
- else
- switch (curcell->attrib)
- {
- case TEXTCELL:
- writef (1, 23, CELLTYPECOLOR, 80, "%s%d %s",
- colstr, currow + 1, MSGTEXT);
- break;
-
- case VALUE:
- writef (1, 23, CELLTYPECOLOR, 80, "%s%d %s",
- colstr, currow + 1, MSGVALUE);
- break;
-
- case FORMULA:
- writef (1, 23, CELLTYPECOLOR, 80, "%s%d %s",
- colstr, currow + 1, MSGFORMULA);
- break;
- }
- writef (1, 24, CELLCONTENTSCOLOR, 80, "%s", s);
- formdisplay = !formdisplay;
- }
-
- VOID displayscreen (INT updating)
- {
- for (row = toprow; row <= bottomrow; row++)
- displayrow (row, updating);
- clearlastcol ();
- }
-
- VOID displayrow (INT row, INT updating)
- {
- for (col = leftcol; col <= rightcol; col++)
- displaycell (col, row, NOHIGHLIGHT, updating);
- }
-
- VOID displaycol (INT col, INT updating)
- {
- for (row = toprow; row <= bottomrow; row++)
- displaycell (col, row, NOHIGHLIGHT, updating);
- }
-
- VOID displaycell (INT col, INT row, INT highlighting,
- INT updating)
- {
- if (loading == 1) return;
- if ((updating) &&
- ((cell [col] [row] == NULL) ||
- (cell [col] [row]->attrib != FORMULA)))
- return;
- s = cellstring (col, row, &color, FORMAT);
- if (highlighting || (col >= curcol && col <= curcolb &&
- row >= currow && row <= currowb &&
- (curcol != curcolb || currow != currowb)))
- {
- if (color == ERRORCOLOR)
- color = HIGHLIGHTERRORCOLOR;
- else
- color = HIGHLIGHTCOLOR;
- }
- writef (colstart [col - leftcol] + 1,
- row - toprow + 3, color, colwidth [col], "%s", s);
- }
-
- VOID clearlastcol (VOID)
- {
- if ((col = colstart [rightcol - leftcol] +
- colwidth [rightcol]) < 80)
- scroll (UP, 0, col + 1, 3, 80, SCREENROWS + 2,
- TEXTCOLOR);
- }
-
- //prints the column headings
- VOID printcol (VOID)
- {
- writef (1, 2, HEADERCOLOR, 3, "");
- scroll (UP, 0, 1, 2, 80, 2, HEADERCOLOR);
- for (col = leftcol; col <= rightcol; col++)
- {
- centercolstring (col, colstr);
- writef (colstart [col - leftcol] + 1, 2, HEADERCOLOR,
- colwidth [col], colstr);
- }
- }
-
- VOID insertrow (INT row)
- {
- if (lastrow == MAXROWS - 1)
- {
- for (counter = 0; counter <= lastcol; counter++)
- deletecell (counter, lastrow, NOUPDATE);
- printfreemem ();
- }
- if (row != MAXROWS - 1)
- for (counter = 0; counter < MAXCOLS; counter++)
- {
- MoveMemory (&cell [counter] [row + 1],
- &cell [counter] [row],
- sizeof (CELLPTR) * (MAXROWS - row - 1));
- MoveMemory (&format [counter] [row + 1],
- &format [counter] [row], MAXROWS - row - 1);
- }
- for (counter = 0; counter < MAXCOLS; counter++)
- {
- cell [counter] [row] = NULL;
- format [counter] [row] = DEFAULTFORMAT;
- }
- lastrow = MAXROWS - 1;
- setlastrow ();
- for (counter = 0; counter <= lastcol; counter++)
- for (rowc = 0; rowc <= lastrow; rowc++)
- if (cell [counter] [rowc] != NULL &&
- cell [counter] [rowc]->attrib == FORMULA)
- fixformula (counter, rowc, ROWADD, row);
- while (row <= bottomrow) displayrow (row++, NOUPDATE);
- changed = TRUE;
- recalc ();
- }
-
- VOID deleterow (INT row)
- {
- for (counter = 0; counter <= lastcol; counter++)
- deletecell (counter, row, NOUPDATE);
- printfreemem ();
- if (row != MAXROWS - 1)
- for (counter = 0; counter < MAXCOLS; counter++)
- {
- MoveMemory (&cell [counter] [row],
- &cell [counter] [row + 1],
- sizeof (CELLPTR) * (MAXROWS - row - 1));
- MoveMemory (&format [counter] [row],
- &format [counter] [row + 1], MAXROWS - row - 1);
- }
- else
- for (counter = 0; counter <= lastcol; counter++)
- {
- cell [counter] [MAXROWS - 1] = NULL;
- format [counter] [MAXROWS - 1] = DEFAULTFORMAT;
- }
- if (lastrow >= row && lastrow > 0) lastrow--;
- for (counter = 0; counter <= lastcol; counter++)
- for (rowc = 0; rowc <= lastrow; rowc++)
- if (cell [counter] [rowc] != NULL &&
- cell [counter] [rowc]->attrib == FORMULA)
- fixformula (counter, rowc, ROWDEL, row);
- while (row <= bottomrow) displayrow (row++, NOUPDATE);
- changed = TRUE;
- recalc ();
- }
-
- VOID insertcol (INT col)
- {
- if (lastcol == MAXCOLS - 1)
- {
- for (counter = 0; counter <= lastrow; counter++)
- deletecell (lastcol, counter, NOUPDATE);
- printfreemem ();
- }
- if (col != MAXCOLS - 1)
- {
- MoveMemory (&cell [col + 1] [0], &cell [col] [0],
- MAXROWS * sizeof (CELLPTR) * (MAXCOLS - col - 1));
- MoveMemory (&format [col + 1] [0], &format [col] [0],
- MAXROWS * (MAXCOLS - col - 1));
- MoveMemory (&colwidth [col + 1], &colwidth [col],
- MAXCOLS - col - 1);
- }
- FillMemory (&cell [col] [0],
- MAXROWS * sizeof (CELLPTR), 0);
- FillMemory (&format [col] [0], MAXROWS, DEFAULTFORMAT);
- colwidth [col] = DEFAULTWIDTH;
- lastcol = MAXCOLS - 1;
- setlastcol ();
- setrightcol ();
- if (curcol > rightcol)
- {
- rightcol++;
- setleftcol ();
- }
- for (counter = 0; counter <= lastcol; counter++)
- for (row = 0; row <= lastrow; row++)
- {
- if (cell [counter] [row] != NULL &&
- cell [counter] [row]->attrib == FORMULA)
- fixformula (counter, row, COLADD, col);
- updateoflags (col, row, NOUPDATE);
- }
- while (col <= rightcol) displaycol (col++, NOUPDATE);
- changed = TRUE;
- recalc ();
- }
-
- VOID deletecol (INT col)
- {
- for (counter = 0; counter <= lastrow; counter++)
- deletecell (col, counter, NOUPDATE);
- printfreemem ();
- if (col != MAXCOLS - 1)
- {
- MoveMemory (&cell [col] [0], &cell [col + 1] [0],
- MAXROWS * sizeof (CELLPTR) * (MAXCOLS - col - 1));
- MoveMemory (&format [col] [0], &format [col + 1] [0],
- MAXROWS * (MAXCOLS - col - 1));
- MoveMemory (&colwidth [col], &colwidth [col + 1],
- MAXCOLS - col - 1);
- }
- FillMemory (&cell [MAXCOLS - 1] [0],
- MAXROWS * sizeof (CELLPTR), 0);
- FillMemory (&format [MAXCOLS - 1] [0], MAXROWS,
- DEFAULTFORMAT);
- colwidth [MAXCOLS - 1] = DEFAULTWIDTH;
- if ((lastcol >= col) && (lastcol > 0)) lastcol--;
- setrightcol ();
- if (curcol > rightcol)
- {
- rightcol++;
- setleftcol ();
- }
- clearlastcol ();
- for (counter = 0; counter <= lastcol; counter++)
- for (row = 0; row <= lastrow; row++)
- {
- if (cell [counter] [row] != NULL &&
- cell [counter] [row]->attrib == FORMULA)
- fixformula (counter, row, COLDEL, col);
- updateoflags (col, row, NOUPDATE);
- }
- while (col <= rightcol) displaycol (col++, NOUPDATE);
- changed = TRUE;
- recalc ();
- }
-
- VOID formatcells (VOID)
- {
- newformat = 0;
- if (!getyesno (&temp, MSGRIGHTJUST)) return;
- newformat += (temp == 'Y') * RJUSTIFY;
- if (!getyesno (&temp, MSGDOLLAR)) return;
- newformat += (temp == 'Y') * DOLLAR;
- if (!getyesno (&temp, MSGCOMMAS)) return;
- newformat += (temp == 'Y') * COMMAS;
- if (newformat & DOLLAR)
- newformat += 2;
- else
- {
- writef (1, 24, PROMPTCOLOR, 80, MSGPLACES);
- if (!getint (&temp, 0, MAXPLACES)) return;
- newformat += temp;
- }
- for (col = curcol; col <= curcolb; col++)
- for (row = currow; row <= currowb; row++)
- format [col] [row] = (format [col] [row] &
- OVERWRITE) | newformat;
- displayscreen (NOUPDATE);
- }
-
- VOID setcolwidth (INT col)
- {
- writef (1, 24, PROMPTCOLOR, 80, MSGCOLWIDTH);
- if (!getint (&width, MINCOLWIDTH, MAXCOLWIDTH)) return;
- colwidth [col] = width;
- setrightcol ();
- if (rightcol < col)
- {
- rightcol = col;
- setleftcol ();
- setrightcol ();
- }
- for (row = 0; row <= lastrow; row++)
- {
- if (cell [col] [row] != NULL &&
- cell [col] [row]->attrib == TEXTCELL)
- clearoflags (col + 1, row, NOUPDATE);
- else
- clearoflags (col, row, NOUPDATE);
- updateoflags (col, row, NOUPDATE);
- }
- displayscreen (NOUPDATE);
- }
-
- INT pagerows (INT row, INT toppage, INT border)
- {
- INT rows;
- rows = toppage ? 66 - TOPMARGIN : 66;
- if (border) rows--;
- if (row + rows - 1 > lastrow)
- return (lastrow - row + 1);
- else
- return (rows);
- }
-
- INT pagecols (INT col, INT border, INT columns)
- {
- INT len = ((col == 0) && (border)) ? columns -
- LEFTMARGIN : columns;
- INT firstcol = col;
- while ((len > 0) && (col <= lastcol))
- len -= colwidth [col++];
- if (len < 0) col--;
- return (col - firstcol);
- }
-
- VOID printsheet (VOID)
- {
- CHAR filename [MAXINPUT + 1], s [133],
- colstr [MAXCOLWIDTH + 1];
- FILE *file;
- INT columns, counter1, counter2, counter3, col = 0,
- row, border, toppage, lcol, lrow, dummy, printed,
- oldlastcol;
- filename [0] = 0;
- lstrcpy (filename, "~.prn");
- if ((file = fopen (filename, "wt")) == NULL)
- {
- errormsg (MSGNOOPEN);
- return;
- }
- oldlastcol = lastcol;
- for (counter1 = 0; counter1 <= lastrow; counter1++)
- for (counter2 = lastcol; counter2 < MAXCOLS;
- counter2++)
- if (format [counter2] [counter1] >= OVERWRITE)
- lastcol = counter2;
- if (!getyesno (&columns, MSGCOLUMNS)) return;
- columns = (columns == 'Y') ? 131 : 79;
- if (!getyesno (&border, MSGBORDER)) return;
- border = (border == 'Y');
- while (col <= lastcol)
- {
- row = 0;
- toppage = TRUE;
- lcol = pagecols (col, border, columns) + col;
- while (row <= lastrow)
- {
- lrow = pagerows (row, toppage, border) + row;
- printed = 0;
- if (toppage)
- for (counter1 = 0; counter1 < TOPMARGIN;
- counter1++)
- {
- fprintf (file, "\n");
- }
- for (counter1 = row; counter1 < lrow; counter1++)
- {
- if (border && counter1 == row && toppage)
- {
- if (col == 0 && border)
- sprintf (s, "%*s", LEFTMARGIN, "");
- else
- s [0] = 0;
- for (counter3 = col; counter3 < lcol;
- counter3++)
- {
- centercolstring (counter3, colstr);
- strcat (s, colstr);
- }
- OemToChar (s, s);
- fprintf (file, "%s\n", s);
- printed++;
- }
- if (col == 0 && border)
- sprintf (s, "%-*d", LEFTMARGIN, counter1 + 1);
- else
- s [0] = 0;
- for (counter2 = col; counter2 < lcol; counter2++)
- strcat (s, cellstring (counter2, counter1,
- &dummy, FORMAT));
- OemToChar (s, s);
- fprintf (file, "%s\n", s);
- printed++;
- }
- row = lrow;
- toppage = FALSE;
- }
- col = lcol;
- }
- fclose (file);
- lastcol = oldlastcol;
- ShellExecute (NULL, "open", "wordpad", "~.prn",
- "", SW_SHOWDEFAULT);
- }
-
- VOID addformula (VOID)
- {
- cstr [1] = 0;
- for (ii = 0; cellptr->v.f.formula [ii] != 0; ii++)
- {
- jj = ii;
- fstr = cellptr->v.f.formula + jj;
- if (formulastart (&fstr, &cl, &rw) &&
- *(fstr++) == ':' &&
- formulastart (&fstr, &cl, &rw))
- {
- lstrcat (str, "SUM(");
- jj = ii + fstr - cellptr->v.f.formula - jj;
- for (n = ii; n < jj; n++)
- {
- cstr [0] = cellptr->v.f.formula [n];
- lstrcat (str, cstr);
- }
- lstrcat (str, ")");
- ii = jj - 1;
- }
- else
- {
- cstr [0] = cellptr->v.f.formula [ii];
- lstrcat (str, cstr);
- }
- }
- }
-
- UINT APIENTRY hookproc2 (HWND hdlg, UINT uimsg,
- WPARAM wparam, LPARAM lparam)
- {
- SetForegroundWindow (GetParent (hdlg));
- return 0;
- }
-
- INT copys (VOID)
- {
- fsize = 0;
- for (row = currow; row <= currowb; row++)
- {
- for (col = curcol; col <= curcolb; col++)
- {
- if (cell [col] [row] != NULL)
- {
- cellptr = cell [col] [row];
- switch (cellptr->attrib)
- {
- case TEXTCELL:
- fsize = fsize + lstrlen (cellptr->v.text);
- break;
-
- case VALUE:
- sprintf (str, "%1.*f", format [col] [row] &
- 15, cellptr->v.value);
- fsize = fsize + lstrlen (str);
- break;
-
- case FORMULA:
- if (formdisplay)
- {
- lstrcpy (str, "=");
- fixformula2 (col, row, -curcol, -currow);
- addformula ();
- fixformula2 (col, row, curcol, currow);
- fsize = fsize + lstrlen (str);
- }
- else
- {
- sprintf (str, "%1.*f", format [col] [row] &
- 15, cellptr->v.value);
- fsize = fsize + lstrlen (str);
- }
- break;
- }
- }
- if (col != lastcol) fsize++;
- }
- fsize = fsize + 2;
- }
- ctext = GlobalAlloc (GMEM_MOVEABLE |
- GMEM_DDESHARE, fsize + 1);
- if (ctext == NULL) return (FALSE);
- ftext = (LPSTR) GlobalLock (ctext);
- ftext [0] = 0;
- for (row = currow; row <= currowb; row++)
- {
- for (col = curcol; col <= curcolb; col++)
- {
- lstrcpy (str, "");
- if (cell [col] [row] != NULL)
- {
- cellptr = cell [col] [row];
- switch (cellptr->attrib)
- {
- case TEXTCELL:
- lstrcpy (str, cellptr->v.text);
- break;
-
- case VALUE:
- sprintf (str, "%1.*f", format [col] [row] &
- 15, cellptr->v.value);
- fsize = fsize + lstrlen (str);
- break;
-
- case FORMULA:
- if (formdisplay)
- {
- lstrcpy (str, "=");
- fixformula2 (col, row, -curcol, -currow);
- addformula ();
- fixformula2 (col, row, curcol, currow);
- }
- else
- sprintf (str, "%1.*f", format [col] [row] &
- 15, cellptr->v.value);
- break;
- }
- }
- lstrcat (ftext, str);
- str [0] = 9;
- str [1] = 0;
- if (col != curcolb) lstrcat (ftext, str);
- }
- str [1] = 0;
- str [0] = 13;
- lstrcat (ftext, str);
- str [0] = 10;
- lstrcat (ftext, str);
- }
- OemToChar (ftext, ftext);
- return (TRUE);
- }
-
- VOID savesheet (VOID)
- {
- ZeroMemory (&ofn, sizeof (ofn));
- ofn.lStructSize = sizeof (ofn);
- ofn.hwndOwner = NULL;
- ofn.lpstrFile = filename;
- ofn.nMaxFile = MAX_PATH;
- ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY |
- OFN_OVERWRITEPROMPT | OFN_ENABLEHOOK;
- ofn.lpstrFilter = "Tab Separated "
- "(*.tsv)\0*.tsv\0Text Files (*.txt)\0*.txt\0\0\0";
- ofn.lpstrDefExt = "tsv";
- ofn.lpfnHook = &hookproc2;
- n = GetSaveFileName (&ofn);
- SetActiveWindow (hwndmain);
- if (!n) return;
- writef (1, 25, PROMPTCOLOR, 79, MSGSAVING);
- SetConsoleCursorPosition (so,
- (COORD) {lstrlen (MSGSAVING), 24});
- hfile = CreateFile (filename, GENERIC_WRITE, 0, 0,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
- if (hfile == INVALID_HANDLE_VALUE)
- {
- errormsg (MSGNOOPEN);
- return;
- }
- col1 = curcol;
- row1 = currow;
- col2 = curcolb;
- row2 = currowb;
- ofd = formdisplay;
- formdisplay = 1;
- curcol = currow = 0;
- curcolb = lastcol;
- currowb = lastrow;
- if (!copys ())
- {
- curcol = col1;
- currow = row1;
- curcolb = col2;
- currowb = row2;
- formdisplay = ofd;
- errormsg (MSGLOMEM);
- return;
- }
- if (!WriteFile (hfile, ftext, lstrlen (ftext),
- &written, NULL))
- {
- errormsg (MSGIOERROR);
- CloseHandle (hfile);
- return;
- }
- GlobalFree (ctext);
- if (!CloseHandle (hfile))
- {
- errormsg (MSGIOERROR);
- return;
- }
- writef (1, 25, TEXTCOLOR, lstrlen (MSGSAVING), "");
- SetConsoleCursorPosition (so, (COORD) {0, 24});
- curcol = col1;
- currow = row1;
- curcolb = col2;
- currowb = row2;
- formdisplay = ofd;
- changed = FALSE;
- }
-
- VOID pastes (VOID)
- {
- ftext = (LPSTR) GlobalLock (ctext);
- CharToOem (ftext, ftext);
- ignorep = 0;
- col1 = curcol;
- row1 = currow;
- lstrcpy (str, "");
- loading = 1;
- for (ii = 0; ftext [ii] != 0; ii++)
- {
- for (jj = 0; jj <= 4; jj++) cstr [jj] = 0;
- for (jj = 0; jj <= 3 &&
- *(ftext + ii + jj) != 0; jj++)
- cstr [jj] = *(ftext + ii + jj);
- if (lstrcmpi (cstr, "sum(") == 0)
- {
- ii = ii + 3;
- ignorep = 1;
- }
- else if (ftext [ii] == 10)
- {
- if (lstrlen (str) != 0)
- act (str);
- else
- deletecell (curcol, currow, UPDATE);
- cellptr = cell [curcol] [currow];
- if (cellptr != NULL)
- if (cellptr->attrib == FORMULA)
- fixformula2 (curcol, currow, col1, row1);
- lstrcpy (str, "");
- curcol = col1;
- currow++;
- }
- else if (ftext [ii] == 9)
- {
- if (lstrlen (str) != 0)
- act (str);
- else
- deletecell (curcol, currow, UPDATE);
- cellptr = cell [curcol] [currow];
- if (cellptr != NULL)
- if (cellptr->attrib == FORMULA)
- fixformula2 (curcol, currow, col1, row1);
- lstrcpy (str, "");
- curcol++;
- }
- else if (ftext [ii] == ')' && ignorep == 1)
- ignorep = 0;
- else if (ftext [ii] != 13 && ftext [ii] != '=')
- {
- cstr [1] = 0;
- cstr [0] = ftext [ii];
- if (lstrlen (str) < MAXINPUT) lstrcat (str, cstr);
- }
- }
- curcol = col1;
- currow = row1;
- loading = 0;
- if (!formdisplay && autocalc) recalc ();
- }
-
- VOID loadsheet (BOOL comline)
- {
- reallastcol = reallastrow = 0;
- success = FALSE;
- if (!comline)
- {
- filename [0] = 0;
- ZeroMemory (&ofn, sizeof (ofn));
- ofn.lStructSize = sizeof (ofn);
- ofn.hwndOwner = NULL;
- ofn.lpstrFile = filename;
- ofn.nMaxFile = MAX_PATH;
- ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST |
- OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |
- OFN_ENABLEHOOK;
- ofn.lpstrFilter = "Tab Separated "
- "(*.tsv)\0*.tsv\0Text Files (*.txt)\0*.txt\0\0\0";
- ofn.lpstrDefExt = "tsv";
- ofn.lpfnHook = &hookproc2;
- n = GetOpenFileName (&ofn);
- SetActiveWindow (hwndmain);
- if (!n) return;
- }
- hfile = CreateFile (filename, GENERIC_READ,
- FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
- if (hfile == INVALID_HANDLE_VALUE)
- {
- errormsg (MSGNOOPEN);
- return;
- }
- clearsheet ();
- writef (1, 25, PROMPTCOLOR, 79, MSGLOADING);
- SetConsoleCursorPosition (so,
- (COORD) {lstrlen (MSGLOADING), 24});
- fsize = GetFileSize (hfile, NULL);
- if (fsize != 0xFFFFFFFF)
- {
- ctext = GlobalAlloc (GMEM_MOVEABLE |
- GMEM_DDESHARE, fsize + 1);
- if (ctext != NULL)
- {
- ftext = (LPSTR) GlobalLock (ctext);
- if (ReadFile (hfile, ftext, fsize,
- &written, NULL))
- {
- ftext [fsize] = 0;
- success = TRUE;
- }
- }
- }
- if (success == FALSE)
- {
- errormsg (MSGIOERROR);
- return;
- }
- if (!CloseHandle (hfile))
- {
- errormsg (MSGIOERROR);
- return;
- }
- loading = 1;
- pastes ();
- loading = 0;
- displayscreen (NOUPDATE);
- writef (1, 25, TEXTCOLOR, lstrlen (MSGLOADING), "");
- SetConsoleCursorPosition (so, (COORD) {0, 24});
- printfreemem ();
- GlobalFree (ctext);
- curcol = currow = curcolb = currowb = 0;
- setrightcol ();
- displayscreen (NOUPDATE);
- changed = FALSE;
- }
-
- VOID initvars (VOID)
- {
- leftcol = toprow = curcol = currow = lastcol =
- lastrow = curcolb = currowb = 0;
- FillMemory (colwidth, sizeof (colwidth), DEFAULTWIDTH);
- FillMemory (cell, sizeof (cell), 0);
- FillMemory (format, sizeof (format), DEFAULTFORMAT);
- }
-
- VOID clearsheet (VOID)
- {
- for (row = 0; row <= lastrow; row++)
- for (col = 0; col <= lastcol; col++)
- deletecell (col, row, NOUPDATE);
- initvars ();
- setrightcol ();
- setbottomrow ();
- curcolb = curcol;
- currowb = currow;
- displayscreen (NOUPDATE);
- printfreemem ();
- changed = FALSE;
- }
-
- VOID editcell (CELLPTR ecell)
- {
- if (ecell == NULL) return;
- switch (ecell->attrib)
- {
- case TEXTCELL: lstrcpy (str, ecell->v.text); break;
-
- case VALUE:
- if (ecell->v.value == HUGE_VAL)
- lstrcpy (str, "0");
- else
- sprintf (str, "%.*f", MAXPLACES, ecell->v.value);
- break;
-
- case FORMULA:
- lstrcpy (str, ecell->v.f.formula);
- break;
- }
- if (!editstring (str, "", MAXINPUT) || (str [0] == 0))
- return;
- act (str);
- changed = TRUE;
- }
-
- VOID changeformdisplay (INT newmode)
- {
- formdisplay = newmode;
- if (formdisplay)
- strcpy (str, MSGFORMDISPLAY);
- else
- str [0] = 0;
- writef (65, 1, MSGFORMDISPLAYCOLOR,
- lstrlen (MSGFORMDISPLAY), str);
- if (!formdisplay && autocalc) recalc ();
- }
-
- VOID changeautocalc (INT newmode)
- {
- if (!autocalc && newmode) recalc ();
- autocalc = newmode;
- if (autocalc)
- strcpy (str, MSGAUTOCALC);
- else
- str [0] = 0;
- writef (73, 1, MSGAUTOCALCCOLOR, lstrlen (MSGAUTOCALC),
- str);
- }
-
- VOID recalc (VOID)
- {
- for (col = 0; col <= lastcol; col++)
- for (row = 0; row <= lastrow; row++)
- if ((cell [col] [row] != NULL) &&
- (cell [col] [row]->attrib == FORMULA))
- cell [col] [row]->v.f.fvalue =
- parse (cell [col] [row]->v.f.formula, &dummy);
- displayscreen (UPDATE);
- }
-
- VOID movecolright(VOID)
- {
- MoveMemory (oldcolstart, colstart, sizeof (colstart));
- oldleftcol = leftcol;
- oldrightcol = rightcol;
- if (curcolb == curcol)
- displaycell (curcol, currow, NOHIGHLIGHT, NOUPDATE);
- if (curcol < rightcol && curcolb < rightcol)
- {
- if (curcolb == curcol && currowb == currow)
- {
- curcol++;
- curcolb = curcol;
- }
- }
- else
- if (rightcol < (MAXCOLS - 1))
- {
- if (currowb == currow && curcolb == curcol)
- {
- curcol++;
- curcolb = curcol;
- }
- rightcol++;
- setleftcol ();
- setrightcol ();
- if (oldrightcol >= leftcol)
- scroll (LEFT,
- oldcolstart [leftcol - oldleftcol] -
- LEFTMARGIN, LEFTMARGIN + 1, 3, 80,
- SCREENROWS + 2, TEXTCOLOR);
- clearlastcol ();
- for (col = oldrightcol + 1; col <= rightcol; col++)
- displaycol (col, NOUPDATE);
- }
- }
-
- VOID movecolleft (VOID)
- {
- oldleftcol = leftcol;
- MoveMemory (oldcolstart, colstart, sizeof (colstart));
- if (curcolb == curcol)
- displaycell (curcol, currow, NOHIGHLIGHT, NOUPDATE);
- if (curcol > leftcol && curcolb > leftcol)
- {
- if (curcolb == curcol && currowb == currow)
- {
- curcol--;
- curcolb = curcol;
- }
- }
- else
- if (leftcol != 0)
- {
- if (currowb == currow && curcolb == curcol)
- {
- curcol--;
- curcolb = curcol;
- }
- leftcol--;
- setrightcol ();
- setleftcol ();
- if (oldleftcol <= rightcol)
- scroll (RIGHT, colstart[oldleftcol - leftcol] -
- LEFTMARGIN, LEFTMARGIN + 1, 3, 80,
- SCREENROWS + 2, TEXTCOLOR);
- clearlastcol ();
- for (col = leftcol; col <= oldleftcol - 1; col++)
- displaycol (col, NOUPDATE);
- }
- }
-
- VOID moverowdown (VOID)
- {
- if (currowb == currow)
- displaycell (curcol, currow, NOHIGHLIGHT, NOUPDATE);
- if (currow < bottomrow && currowb < bottomrow)
- {
- if (currowb == currow && curcolb == curcol)
- {
- currow++;
- currowb = currow;
- }
- }
- else
- if (bottomrow < MAXROWS - 1)
- {
- scroll (UP, 1, LEFTMARGIN + 1, 3, 80,
- SCREENROWS + 2, TEXTCOLOR);
- toprow++;
- if (currowb == currow && curcolb == curcol)
- {
- currow++;
- currowb = currow;
- }
- setbottomrow ();
- displayrow (bottomrow, NOUPDATE);
- }
- }
-
- VOID moverowup (VOID)
- {
- if (currowb == currow)
- displaycell (curcol, currow, NOHIGHLIGHT, NOUPDATE);
- if (currow > toprow && currowb > toprow)
- {
- if (currowb == currow && curcolb == curcol)
- {
- currow--;
- currowb = currow;
- }
- }
- else
- if (toprow != 0)
- {
- scroll (DOWN, 1, LEFTMARGIN + 1, 3, 80,
- SCREENROWS + 2, TEXTCOLOR);
- displayrow (--toprow, NOUPDATE);
- if (currowb == currow && curcolb == curcol)
- {
- currow--;
- currowb = currow;
- }
- setbottomrow ();
- }
- }
-
- //reads in a command and acts on it
- INT getcommand (LPSTR msgstr, LPSTR comstr)
- {
- len = lstrlen (msgstr);
- scroll (UP, 0, 1, 24, 80, 24, TEXTCOLOR);
- for (counter = 0; counter < len; counter++)
- {
- if (IsCharUpper (msgstr [counter]))
- writef (counter + 1, 24, COMMANDCOLOR, 1, "%c",
- msgstr [counter]);
- else
- writef (counter + 1, 24, LOWCOMMANDCOLOR, 1, "%c",
- msgstr [counter]);
- }
- do
- ch = (CHAR) CharUpper ((LPSTR) getkey ());
- while (strchr (comstr, ch) == NULL && ch != ESC);
- scroll (UP, 0, 1, 25, 80, 25, TEXTCOLOR);
- SetConsoleCursorPosition (so, (COORD) {0, 24});
- if (ch == ESC) return (-1);
- return (lstrlen (comstr) -
- lstrlen (strchr (comstr, ch)));
- }
-
- VOID mainmenu (VOID)
- {
- switch (getcommand (MENU, COMMAND))
- {
- case 0:
- switch (getcommand (SMENU, SCOMMAND))
- {
- case 0:
- if (changed && getyesno (&i,
- MSGSAVESHEET) && i == 'Y')
- savesheet ();
- loadsheet (FALSE);
- break;
-
- case 1: savesheet (); break;
- case 2: printsheet (); break;
-
- case 3:
- if (changed && getyesno (&i,
- MSGSAVESHEET) && i == 'Y')
- savesheet ();
- clearsheet ();
- break;
-
- case 4:
- lstrcpy (str, MSGABOUT1);
- lstrcat (str, MSGABOUT2);
- MessageBox (NULL, str,
- "About this program", MB_SETFOREGROUND);
- break;
- }
- break;
-
- case 1: formatcells (); break;
-
- case 2:
- deletecell (curcol, currow, UPDATE);
- printfreemem ();
- if (autocalc) recalc ();
- break;
-
- case 3:
- if (curcolb == curcol && currowb == currow)
- {
- writef (1, 24, PROMPTCOLOR, 80, MSGGOTO);
- if (getcell (&curcol, &currow))
- {
- leftcol = curcol;
- toprow = currow;
- setbottomrow ();
- setrightcol ();
- setleftcol ();
- displayscreen (NOUPDATE);
- }
- }
- break;
-
- case 4:
- if (curcolb == curcol && currowb == currow)
- switch (getcommand (CMENU, CCOMMAND))
- {
- case 0: insertcol (curcol); break;
- case 1: deletecol (curcol); break;
- case 2: setcolwidth (curcol); break;
- }
- break;
-
- case 5:
- if (curcolb == curcol && currowb == currow)
- switch (getcommand (RMENU, RCOMMAND))
- {
- case 0: insertrow (currow); break;
- case 1: deleterow (currow); break;
- }
- break;
-
- case 6: editcell (curcell); break;
-
- case 7:
- switch (getcommand (UMENU, UCOMMAND))
- {
- case 0: recalc (); break;
-
- case 1:
- changeformdisplay (!formdisplay);
- displayscreen (UPDATE);
- break;
- }
- break;
-
- case 8: changeautocalc (!autocalc); break;
-
- case 9:
- if (changed && getyesno (&i,
- MSGSAVESHEET) && i == 'Y')
- savesheet ();
- stop = TRUE;
- break;
- }
- }
-
- UINT APIENTRY hookproc1 (HWND hdlg, UINT uimsg,
- WPARAM wparam, LPARAM lparam)
- {
- ShowWindow (hdlg, 0);
- PostMessage (hdlg, WM_COMMAND, IDABORT, 0);
- EndDialog (hdlg, 1);
- hwndmain = GetParent (hdlg);
- SetForegroundWindow (hwndmain);
- return 0;
- }
-
- VOID main (INT argc, LPSTR argv [])
- {
- si = GetStdHandle (STD_INPUT_HANDLE);
- so = GetStdHandle (STD_OUTPUT_HANDLE);
- SetConsoleMode (si, ENABLE_WINDOW_INPUT);
- SetConsoleTitle (MSGTITLE);
- setcursor (shortcursor);
- setcursor (nocursor);
- changed = formdisplay = stop = FALSE;
- autocalc = TRUE;
- loading = coord.X = 0;
- for (coord.Y = 0; coord.Y <= 24; coord.Y++)
- FillConsoleOutputCharacter
- (so, ' ', 80, coord, &written);
- for (coord.Y = 0; coord.Y <= 79; coord.Y++)
- FillConsoleOutputAttribute
- (so, TEXTCOLOR, 80, coord, &written);
- ZeroMemory (&ofn, sizeof (ofn));
- ofn.lStructSize = sizeof (ofn);
- ofn.hwndOwner = NULL;
- ofn.lpstrFile = filename;
- ofn.nMaxFile = MAX_PATH;
- ofn.Flags = OFN_ENABLEHOOK;
- ofn.lpstrFilter = "0\0\0\0\0";
- ofn.lpstrDefExt = "";
- ofn.lpfnHook = &hookproc1;
- GetOpenFileName(&ofn);
- initvars ();
- setrightcol ();
- setbottomrow ();
- writef (1, 1, MSGMEMORYCOLOR, lstrlen (MSGMEMORY),
- MSGMEMORY);
- writef (29, 1, PROMPTCOLOR, lstrlen (MSGCOMMAND),
- MSGCOMMAND);
- changeautocalc (autocalc);
- changeformdisplay (formdisplay);
- printfreemem ();
- displayscreen (NOUPDATE);
- if (argc > 1)
- {
- lstrcpy (filename, argv [1]);
- for (i = 0; filename [i] != '.'; i++);
- for (j = 0; j <= 2; j++)
- str [j] = filename [i + j + 1];
- str [3] = 0;
- if (lstrcmpi (str, "tsv") == 0 ||
- lstrcmpi (str, "txt") == 0)
- loadsheet (TRUE);
- }
- scroll (UP, 0, 1, 25, 80, 25, TEXTCOLOR);
- SetConsoleCursorPosition (so, (COORD) {0, 24});
- do
- {
- if (curcol == curcolb && currow == currowb)
- displaycell (curcol, currow, HIGHLIGHT, NOUPDATE);
- else
- displayscreen (NOUPDATE);
- curcell = cell [curcol] [currow];
- showcelltype ();
- inpt = getkey ();
- switch (inpt)
- {
- case '/': mainmenu (); break;
- case F9: recalc (); break;
- case F2: editcell (curcell); break;
-
- case SHIFTF9:
- changeformdisplay (!formdisplay);
- displayscreen (UPDATE);
- break;
-
- case DELKEY:
- for (ii = currow; ii <= currowb; ii++)
- for (jj = curcol; jj <= curcolb; jj++)
- deletecell (jj, ii, UPDATE);
- printfreemem ();
- if (autocalc) recalc ();
- break;
-
- case PGUPKEY:
- if (curcolb == curcol && currowb == currow)
- {
- toprow -= 20;
- currow -= 20;
- if (currow < 0)
- currow = toprow = 0;
- else
- if (toprow < 0)
- {
- currow -= toprow;
- toprow = 0;
- }
- currowb = currow;
- setbottomrow ();
- displayscreen (NOUPDATE);
- }
- break;
-
- case PGDNKEY:
- if (curcolb == curcol && currowb == currow)
- {
- toprow += 20;
- currow += 20;
- if ((currow >= MAXROWS) && (toprow >= MAXROWS))
- {
- currow = MAXROWS - 1;
- toprow = MAXROWS - 20;
- }
- else
- if (toprow > (MAXROWS - 20))
- {
- currow -= (toprow + 20 - MAXROWS);
- toprow = MAXROWS - 20;
- }
- currowb = currow;
- setbottomrow ();
- displayscreen (NOUPDATE);
- }
- break;
-
- case CTRLLEFTKEY:
- if (curcolb == curcol && currowb == currow)
- {
- displaycell (curcol, currow, NOHIGHLIGHT,
- NOUPDATE);
- if (leftcol == 0)
- {
- curcol = 0;
- curcolb = curcol;
- }
- else
- {
- curcol = rightcol = leftcol - 1;
- curcolb = curcol;
- setleftcol ();
- setrightcol ();
- displayscreen (NOUPDATE);
- }
- }
- break;
-
- case CTRLRIGHTKEY:
- if (curcolb == curcol && currowb == currow)
- {
- displaycell (curcol, currow, NOHIGHLIGHT,
- NOUPDATE);
- if (rightcol == MAXCOLS - 1)
- {
- curcol = rightcol;
- curcolb = curcol;
- }
- else
- {
- curcol = leftcol = rightcol + 1;
- curcolb = curcol;
- setrightcol ();
- setleftcol ();
- displayscreen (NOUPDATE);
- }
- }
- break;
-
- case HOMEKEY:
- if (curcolb == curcol && currowb == currow)
- {
- currow = curcol = leftcol = toprow = 0;
- currowb = currow;
- curcolb = curcol;
- setrightcol ();
- setbottomrow ();
- displayscreen (NOUPDATE);
- }
- break;
-
- case ENDKEY:
- if (curcolb == curcol && currowb == currow)
- {
- rightcol = curcol = lastcol;
- currow = bottomrow = lastrow;
- currowb = currow;
- curcolb = curcol;
- if (bottomrow - SCREENROWS < -1)
- bottomrow = 19;
- toprow = bottomrow - 19;
- for (row = 0; row < SCREENROWS; row++)
- writef (1, row + 3, HEADERCOLOR, LEFTMARGIN, "%-d",
- row + toprow + 1);
- setleftcol ();
- setrightcol ();
- displayscreen (NOUPDATE);
- }
- break;
-
- case SHIFTENDKEY:
- rightcol = lastcol;
- bottomrow = lastrow;
- currowb = lastrow;
- curcolb = lastcol;
- if (bottomrow - SCREENROWS < -1)
- bottomrow = 19;
- toprow = bottomrow - 19;
- for (row = 0; row < SCREENROWS; row++)
- writef (1, row + 3, HEADERCOLOR, LEFTMARGIN, "%-d",
- row + toprow + 1);
- setbottomrow ();
- setleftcol ();
- setrightcol ();
- displayscreen (NOUPDATE);
- break;
-
- case UPKEY:
- if (curcolb != curcol || currowb != currow)
- {
- curcolb = curcol;
- currowb = currow;
- leftcol = leftcolb;
- toprow = toprowb;
- setbottomrow ();
- setrightcol ();
- setleftcol ();
- displayscreen (NOUPDATE);
- }
- else
- moverowup ();
- break;
-
- case DOWNKEY:
- if (curcolb != curcol || currowb != currow)
- {
- curcolb = curcol;
- currowb = currow;
- leftcol = leftcolb;
- toprow = toprowb;
- setbottomrow ();
- setrightcol ();
- setleftcol ();
- displayscreen (NOUPDATE);
- }
- else
- moverowdown ();
- break;
-
- case LEFTKEY:
- if (curcolb != curcol || currowb != currow)
- {
- curcolb = curcol;
- currowb = currow;
- leftcol = leftcolb;
- toprow = toprowb;
- setbottomrow ();
- setrightcol ();
- setleftcol ();
- displayscreen (NOUPDATE);
- }
- else
- movecolleft ();
- break;
-
- case RIGHTKEY:
- if (curcolb != curcol || currowb != currow)
- {
- curcolb = curcol;
- currowb = currow;
- leftcol = leftcolb;
- toprow = toprowb;
- setbottomrow ();
- setrightcol ();
- setleftcol ();
- displayscreen (NOUPDATE);
- }
- else
- movecolright ();
- break;
-
- case SHIFTUPKEY:
- if (currow <= currowb - 1)
- {
- currowb--;
- if (curcol == curcolb && currow == currowb)
- displayscreen (NOUPDATE);
- else
- moverowup ();
- }
- break;
-
- case SHIFTDOWNKEY:
- if (currowb == currow && curcolb == curcol)
- {
- leftcolb = leftcol;
- toprowb = toprow;
- }
- if (MAXROWS >= currowb + 1)
- {
- currowb++;
- moverowdown ();
- }
- break;
-
- case SHIFTLEFTKEY:
- if (curcol <= curcolb - 1)
- {
- curcolb--;
- if (curcol == curcolb && currow == currowb)
- displayscreen (NOUPDATE);
- else
- movecolleft ();
- }
- break;
-
- case SHIFTRIGHTKEY:
- if (currowb == currow && curcolb == curcol)
- {
- leftcolb = leftcol;
- toprowb = toprow;
- }
- if (MAXROWS >= curcolb + 1)
- {
- curcolb++;
- movecolright ();
- }
- break;
-
- case CTRLC:
- if (!copys ())
- {
- errormsg (MSGLOMEM);
- break;
- }
- GlobalUnlock (ctext);
- if (!OpenClipboard (NULL) ||
- !EmptyClipboard () ||
- SetClipboardData (CF_TEXT, ctext) == NULL)
- {
- CloseClipboard ();
- GlobalFree (ctext);
- break;
- }
- CloseClipboard ();
- break;
-
- case CTRLV:
- if (!OpenClipboard (NULL) ||
- (ctext = GetClipboardData (CF_TEXT)) == NULL)
- {
- CloseClipboard ();
- break;
- }
- pastes ();
- GlobalUnlock (ctext);
- CloseClipboard ();
- changed = TRUE;
- displayscreen (NOUPDATE);
- break;
-
- case ALTF4:
- if (changed && getyesno (&i,
- MSGSAVESHEET) && i == 'Y')
- savesheet ();
- stop = TRUE;
- break;
-
- case ESC: case BS: case CR: case INSKEY:
- case TABKEY: case F4:
- break;
-
- default:
- stri [0] = inpt;
- stri [1] = 0;
- if (editstring (stri, "", MAXINPUT) &&
- stri [0] != 0)
- {
- act (stri);
- changed = TRUE;
- }
- break;
- }
- }
- while (!stop);
- }
-
-